2009-11-01 89 views
3

我有元组的列表:二郎列表操作

L = [{1, [a, b, c]}, {2, [d, e, f]}, {3, [[h, i, j], [k, l, m]]}] 

这是我

lists:map(fun({_, B}-> B end, L). 

输出

[[a, b, c], [d, e, f], [[h, i, j], [k, l, m]]] 

我要的是:

[[a, b, c], [d, e, f], [h, i, j], [k, l, m]] 

这似乎是一个很容易的问题,但我无法弄清楚如何去做。 请帮忙!

回答

5

让我们来看看...

1> L = [{1, [a, b, c]}, {2, [d, e, f]}, {3, [[h, i, j], [k, l, m]]}]. 
[{1,[a,b,c]},{2,[d,e,f]},{3,[[h,i,j],[k,l,m]]}] 

琐碎而简单,但不是尾递归:

2> lists:foldr(fun ({_,[X|_]=E},A) when is_list(X) -> lists:append(A,E); 
        ({_,E},A) -> [E|A] end, 
       [], L). 
[[a,b,c],[d,e,f],[h,i,j],[k,l,m]] 

由于不是尾递归是不是很漂亮,但是,但是...

3> lists:reverse(lists:foldl(fun ({_,[X|_]=E},A) when is_list(X) -> 
            lists:reverse(E,A); 
           ({_,E},A) -> [E|A] end, 
          [], L)). 
[[a,b,c],[d,e,f],[h,i,j],[k,l,m]] 

...尾递归版本也有效(感谢Zed指出lists:reverse/2)。

+0

一个问题,你用列表:追加(名单:反向(E),A )然后在最后反转整个事情,只是为了避免将结果追加到A的末尾,以提高性能? – Quincy 2009-11-02 01:43:19

+3

@ndim:lists:reverse(E,A)=:= lists:append(lists:reverse(E),A) – Zed 2009-11-02 10:36:58

+0

@Quincy:追加到A的结尾需要每次遍历列表。这并没有规模。因此,您建立反向列表,并完成一个列表:反向/ 1呼叫。这是Erlang的标准操作程序。另外,不像'lists:foldr/3','lists:foldl/3'被记录为使用尾递归,因此需要更少的堆栈,并且由于在规范方向上遍历列表而更快。总而言之,'lists:foldl/3'解决方案应该是最强大的。 – ndim 2009-11-02 13:45:35

2

针对您的特殊情况下,例如,您可以定义以下功能:

group3([], Acc) -> 
    Acc; 
group3([A,B,C|Tl], Acc) -> 
    group3(Tl, [[A,B,C]] ++ Acc). 

group3(L) -> 
    lists:reverse(group3(L, [])). 

并调用它像这样:

group3(lists:flatten(lists:map(fun({_, B}) -> B end, L))). 

希望这足以给你一个总体战略。

+0

太糟糕了它应该采取与长度为N感谢您的努力名单虽然 – Quincy 2009-11-02 00:53:13

1
-module(z). 
-export([do/1]). 

do([{_,[X|_] = L}|Tl]) when is_list(X) -> L ++ do(Tl); 
do([{_, L}  |Tl])     -> [L|do(Tl)]; 
do([])         -> []. 

测试:

1> z:do(L). 
[[a,b,c],[d,e,f],[h,i,j],[k,l,m]]