Fliter from map and add to list

Hi everyone,
I have a list like this,
[
%Component{
allocated_quantity: 1,
component_handle: “q_cdo_01”,
component_id: 8804323,
kind: “quantity_based”,
name: “CALL”,
scheme: “per_unit”,
subscription_id: 313729351,
unit_name: “user”
},
%Component{
allocated_quantity: 1,
component_handle: “q_cdu_01”,
component_id: 8804234,
kind: “quantity_based”,
name: “DUMMY”,
scheme: “per_unit”,
subscription_id: 313729351,
unit_name: “user”
},
%Component{
allocated_quantity: 4,
component_handle: “a_api_01”,
component_id: 9230020,
kind: “quantity_based\t”,
name: “API”,
scheme: “per_unit”,
subscription_id: 313729351,
unit_name: “user”
}
]

I want to filter “a_api_01” and make a separate list .So that I will get output of 2 list.
something like

[%Component{
allocated_quantity: 4,
component_handle: “a_api_01”,
component_id: 9230020,
kind: “quantity_based\t”,
name: “API”,
scheme: “per_unit”,
subscription_id: 313729351,
unit_name: “user”
}] 
[
%Component{
allocated_quantity: 1,
component_handle: “q_cdo_01”,
component_id: 8804323,
kind: “quantity_based”,
name: “CALL”,
scheme: “per_unit”,
subscription_id: 313729351,
unit_name: “user”
},
%Component{
allocated_quantity: 1,
component_handle: “q_cdu_01”,
component_id: 8804234,
kind: “quantity_based”,
name: “DUMMY”,
scheme: “per_unit”,
subscription_id: 313729351,
unit_name: “user”
}]

Is there any way I can do this?

You can use Enum.group_by/3 and Map.values/1 like:

list |> Enum.group_by(& &1.component_handle) |> Map.values()

You would have a list of lists. Each of list would have items with same component_handle.

You can also use String.replace/3 if you want to group items by some pattern:

"a_api_" === String.replace("a_api_01", ~r/\d+$/, "")
"q_cdu_" === String.replace("q_cdu_01", ~r/\d+$/, "")

list
|> Enum.group_by(&String.replace(&1.component_handle, ~r/\d+$/, ""))
|> Map.values()
1 Like

Please note that for better readability, You should enclose your code with ``` as in Markdown :slight_smile:

4 Likes

How about this using Enum.reduce/3?

list |> Enum.reduce({[],[]}, fn (item,{list1,list2}) -> 
          case item do
              %{component_handle: "a_api_01"} -> {[x|list1], list2}
              _ -> {list1, [x|list2]}
          end
       end)

Gives me a two element tuple like below:

{[
   %{
     allocated_quantity: 4,
     component_handle: "a_api_01",
     component_id: 9230020,
     kind: "quantity_based\t",
     name: "API",
     scheme: "per_unit",
     subscription_id: 313729351,
     unit_name: "user"
   }
 ],
 [
   %{
     allocated_quantity: 1,
     component_handle: "q_cdu_01",
     component_id: 8804234,
     kind: "quantity_based",
     name: "DUMMY",
     scheme: "per_unit",
     subscription_id: 313729351,
     unit_name: "user"
   },
   %{
     allocated_quantity: 1,
     component_handle: "q_cdo_01",
     component_id: 8804323,
     kind: "quantity_based",
     name: "CALL",
     scheme: "per_unit",
     subscription_id: 313729351,
     unit_name: "user"
   }
 ]}
1 Like

Thank you… :grinning:

There’s also Enum.split_with/2