【问题标题】:List to list of tuples convertion列表到元组转换列表
【发布时间】:2011-03-08 10:53:47
【问题描述】:

我想将[z,z,a,z,z,a,a,z] 转换为[{z,2},{a,1},{z,2},{a,2},{z,1}]。我该怎么做?

所以,我需要累积以前的值、它的计数器和元组列表。

我已经创建了记录

-record(acc, {previous, counter, tuples}).

重新定义

listToTuples([]) -> [];
listToTuples([H | Tail]) -> 
    Acc = #acc{previous=H, counter=1},
    listToTuples([Tail], Acc).

但是我遇到了一些麻烦

listToTuples([H | Tail], Acc) ->   
    case H == Acc#acc.previous of
        true  ->
        false ->
    end.

【问题讨论】:

    标签: erlang


    【解决方案1】:

    如果你反向建立你的答案 (Acc),前一个将是该列表的头部。

    这就是我的做法--

    list_pairs(List) -> list_pairs(List, []).
    
    list_pairs([], Acc) -> lists:reverse(Acc);
    list_pairs([H|T], [{H, Count}|Acc]) -> list_pairs(T, [{H, Count+1}|Acc]);
    list_pairs([H|T], Acc) -> list_pairs(T, [{H, 1}|Acc]).
    

    (我希望现在有人会使用单行列表理解版本..)

    【讨论】:

    • 我怀疑你可以通过列表理解来做到这一点。你至少需要弃牌。
    【解决方案2】:

    我将继续反向构建列表。注意第一行 X 上的模式匹配。

    F = fun(X,[{X,N}|Rest]) -> [{X,N+1}|Rest];
           (X,Rest)         -> [{X,1}|Rest] end.
    
    lists:foldr(F,[],List).
    

    【讨论】:

    • 使用lists:foldr/3,你就到家了。 ;)
    • 使用lists:foldr/3,您并没有真正反向构建列表,至少与调用使用累加器并调用lists:reverse/1 时的含义不同。 lists:foldr 只在列表上从右到左工作,因此它以相反的顺序处理所有元素,这是 defined 要做的。它不是尾递归的,这并不总是一件坏事。这在文档中有所提及。
    【解决方案3】:

    我会亲自使用lists:foldr/3 或手动使用类似的东西:

    list_to_tuples([H|T]) -> list_to_tuples(T, H, 1);
    list_to_tuples([]) -> [].
    
    list_to_tuples([H|T], H, C) -> list_to_tuples(T, H, C+1);
    list_to_tuples([H|T], P, C) -> [{P,C}|list_to_tuples(T, H, 1);
    list_to_tuples([], P, C) -> [{P,C}].
    

    使用两个累加器可以避免为列表中的每个元素构建和拆分一个元组。我觉得这样写更清楚。

    【讨论】:

      猜你喜欢
      • 2012-06-05
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      • 2022-09-27
      • 2015-02-13
      • 2016-09-28
      • 1970-01-01
      相关资源
      最近更新 更多