Spanning repeatable keys

1> L_tup = [
1>   {"Caerus1", "Ramses Refiner"},
1>   {"Caerus1", "Jupiter Refiner"},
1>   {"Caerus1", "Jupiter Other"},
1>   {"Caerus1", "Trader 13"},
1>   {"Caerus1", "Cathode Supplier 4"},
1>   {"Dionysus3", "Cathode Supplier 4"},
1>   {"Dionysus3", "Ramses Refiner"},
1>   {"Dionysus3", "Trader 13"},
1>   {"Dionysus3", "Jupiter Refiner"},
1>   {"Dionysus3", "Jupiter Other"},
1>   {"Prometheus2", "Jupiter Other"},
1>   {"Prometheus2", "Ramses Refiner"},
1>   {"Prometheus2", "Trader 13"},
1>   {"Prometheus2", "Cathode Supplier 4"},
1>   {"Prometheus2", "Jupiter Refiner"}
1> ].
[{"Caerus1","Ramses Refiner"},
 {"Caerus1","Jupiter Refiner"},
 {"Caerus1","Jupiter Other"},
 {"Caerus1","Trader 13"},
 {"Caerus1","Cathode Supplier 4"},
 {"Dionysus3","Cathode Supplier 4"},
 {"Dionysus3","Ramses Refiner"},
 {"Dionysus3","Trader 13"},
 {"Dionysus3","Jupiter Refiner"},
 {"Dionysus3","Jupiter Other"},
 {"Prometheus2","Jupiter Other"},
 {"Prometheus2","Ramses Refiner"},
 {"Prometheus2","Trader 13"},
 {"Prometheus2","Cathode Supplier 4"},
 {"Prometheus2","Jupiter Refiner"}]
2> F = fun({K,V},Acc) ->                  
2>     case Acc of                        
2>         [#{K:=L}|T] -> [#{K=>[V|L]}|T];
2>         Acc -> [#{K => [V]}|Acc]       
2>     end                                
2> end.                                   
#Fun<erl_eval.43.79398840>
3> lists:foldl(F,[],L_tup).
[#{"Prometheus2" =>
       ["Jupiter Refiner","Cathode Supplier 4","Trader 13",
        "Ramses Refiner","Jupiter Other"]},
 #{"Dionysus3" =>
       ["Jupiter Other","Jupiter Refiner","Trader 13",
        "Ramses Refiner","Cathode Supplier 4"]},
 #{"Caerus1" =>
       ["Cathode Supplier 4","Trader 13","Jupiter Other",
        "Jupiter Refiner","Ramses Refiner"]}]
4>

if the initial list L_tup is not sorted it is necessary to use lists:sort(L_tup).

The former code will have a result looking like the example you give: a list of map. But it is not a map as described in the last sentence. To create a map you can use the next code (this version does not need a sorted input):

4> F1 = fun({K,V},M) ->       
4>     L = maps:get(K,M,[]), 
4>     M#{K=>[V|L]}          
4> end.
#Fun<erl_eval.43.79398840>
5> lists:foldl(F1,#{},L_tup).
#{"Caerus1" =>
      ["Cathode Supplier 4","Trader 13","Jupiter Other",
       "Jupiter Refiner","Ramses Refiner"],
  "Dionysus3" =>
      ["Jupiter Other","Jupiter Refiner","Trader 13",
       "Ramses Refiner","Cathode Supplier 4"],
  "Prometheus2" =>
      ["Jupiter Refiner","Cathode Supplier 4","Trader 13",
       "Ramses Refiner","Jupiter Other"]}
6> % could be written in a single line :o)
6> % lists:foldl(fun({K,V},M) -> M#{K=>[V|maps:get(K,M,[])]} end,#{},L_tup).

Leave a Comment