我需要解析许多关系。
我的列表如下:
[
{item1, [rel1, rel2, rel3]},
{item2, [rel2, rel5]},
{item3, [rel1, rel4]},
...
]
I need to build new list like:
[
{rel1, [item1, item3]},
{rel2, [item1, item2]},
...
]
我怎样才能有效地做到这一点?
答案 0 :(得分:2)
使用dict的最有效方式:
F = fun({Item,Rels}, Dict) ->
H = fun(L) -> [Item|L] end,
G = fun(Rel, D) -> dict:update(Rel, H, [Item], D) end,
lists:foldl(G, Dict, Rels)
end,
dict:to_list(lists:foldl(F, dict:new(), Input)).
由于GC压力较小,使用ets可以更快地获得真正的大数据:
Tab = ets:new(ok, [private]),
[ ets:insert(Tab,
{Rel, case ets:lookup(Tab, Rel) of
[] -> [Item];
[{_, L}] -> [Item|L]
end})
|| {Item, Rels} <- Input, Rel <- Rels ],
Result = ets:tab2list(Tab),
ets:delete(Tab),
Result.
修改强>: 由于R17有地图,因为R18它们即使对于大量的键也应该是高效的,所以现在有更高效的版本使用地图:
F = fun({Item, Rels}, Map) ->
G = fun(Rel, M) -> maps:put(Rel, [Item|maps:get(Rel, M, [])], M) end,
lists:foldl(G, Map, Rels)
end,
maps:to_list(lists:foldl(F, #{}, L)).
答案 1 :(得分:1)
D = dict:from_list(INPUT),
F = fun(K,V,ACC) ->
dict:update(V, fun(X) -> [K|X] end, [X], ACC)
end
D2 = dict:fold(F, dict:new(), D),
OUTPUT = dict:to_list(D2).
答案 2 :(得分:1)
convert_relation(Relations) ->
Dict =
lists:foldl(fun({Item, RelList}, Dict1) ->
lists:foldl(fun(Rel, Dict2) ->
dict:append(Rel, Item, Dict2)
end, Dict1, RelList)
end, dict:new(), Relations),
dict:to_list(Dict).