erlang lists 按key分组

在应用场景中,我们经常需要对 tuple 组成的lists进行分组,本文参考网上的方案,实现了多元组的group by。

1. 原生版本(来自网络,原文链接已找不到,如果有线索,请联系本人)

源码:

group_by([])->
    [];
group_by(KVList) ->
    Fun = fun({K,V}, D) -> dict:append(K, V, D) end,
    dict:to_list(lists:foldr(Fun , dict:new(), KVList)).

测试:L = [{1,2},{1,4},{2,5},{5,6}],group_by(L) .

输出:[{2,[5]},{5,[6]},{1,[4,2]}].

原生版本只支持二元组组成的lists,而且key 一定在元组中的第一个位置。当我们扩展到三元组组成的lists就行不通了。

2. 支持三(多)元组并且支持key在任意位置(不超过size大小)

group_by(KVList, Pos) when is_integer(Pos)->
    Fun = fun(Item, D) ->
        K = element(Pos, Item),
        case erlang:delete_element(Pos, Item) of
            {V} ->
                dict:append(K, V, D);
            V ->
                dict:append(K, V, D)
        end
    end,
    dict:to_list(lists:foldr(Fun , dict:new(), KVList)).

测试代码:z_lib:group_by([{1,2,3}, {2,3,4}, {4,5,6}, {1,3,7}],2).

输出:[{3,[{1,7},{2,4}]},{2,[{1,3}]},{5,[{4,6}]}]
扩展版本满足了三(多)元组并支持key在任意位置,但是如果我们希望可以对两个key进行group by 怎么办呢?下面的版本就是

要做这件事情。

3.  支持2个key嵌套group by,以两个key的情况举例:

group_by([], _, _) ->
    [];
group_by(KVList, Pos1, Pos2) when Pos1 =:= Pos2 ->
    group_by(KVList, Pos1);
group_by(KVList, Pos1, Pos2) when Pos1 < Pos2 ->
    [ {K, group_by(V, Pos2-1)} || {K, V} <- group_by(KVList, Pos1)];
group_by(KVList, Pos1, Pos2) ->
    [ {K, group_by(V, Pos2)} || {K, V} <- group_by(KVList, Pos1)].

测试代码:z_lib:group_by([{1,2,3}, {2,3,4}, {4,5,6}, {1,3,7}], 2,3).

结果输出:[{3,[{4,[2]},{7,[1]}]},{2,[{3,[1]}]},{5,[{6,[4]}]}].

根据上面的思路,很容易扩展到多个key排序的情况。

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值