跨越可重复键

Spanning repeatable keys

来自这样的:

[
  {"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"}
]

我想实现这个:

[
  {"Caerus1" => ["Ramses Refiner", "Jupiter Refiner", "Jupiter Other", "Trader 13", "Cathode Supplier 4"]},
   .
   .
   .
]

所以基本上将这些元组转换为具有唯一键的映射 - 所以它不会重复(我可以轻松做到)困难的部分是制作第二个元素字符串的列表。

提前致谢

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>

如果初始列表 L_tup 未排序,则需要使用 lists:sort(L_tup).

前面的代码会得到类似于您给出的示例的结果:地图列表。但它不是最后一句话描述的地图。要创建地图,您可以使用下一个代码(此版本不需要排序输入):

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).

在 Elixir 中使用 Enum.group_by/3:

很容易
iex> Enum.group_by(values, fn {key, _} -> key end, fn {_, value} -> value end)
%{
  "Caerus1" => ["Ramses Refiner", "Jupiter Refiner", "Jupiter Other",
   "Trader 13", "Cathode Supplier 4"],
  "Dionysus3" => ["Cathode Supplier 4", "Ramses Refiner", "Trader 13",
   "Jupiter Refiner", "Jupiter Other"],
  "Prometheus2" => ["Jupiter Other", "Ramses Refiner", "Trader 13",
   "Cathode Supplier 4", "Jupiter Refiner"]
}