2010-08-13 56 views
5

請告訴我交錯三組數據的易/有效的方法..二郎 - 交錯的簡單方法

Data1 = [<<5>>,<<6>>,<<7>>], 
Data2 = [<<5>>,<<6>>,<<7>>], 
Data3 = [<<5>>,<<6>>,<<7>>]. 

最終結果是:

Final = [<<5>>, <<5>>, <<5>>, <<6>>, <<6>>, <<6>>, <<7>>, <<7>>, <<7>>] 

我敢肯定它像

[X || X <- [Data1, Data2, Data3]] 

回答

2

模塊功能:

zip3(X, Y, Z) when X =:= []; Y =:= []; Z =:= [] -> []; 
zip3([HX | TX], [HY | TY], [HZ | TZ]) -> [ HX, HY, HZ | zip3(TX, TY, TZ)]. 

同樣在外殼:

F = fun(D1, D2, D3) -> 
    G = fun(F, X, Y, Z) when X =:= []; Y =:= []; Z =:= [] -> []; 
     (F, [HX | TX], [HY | TY], [HZ | TZ]) -> [ HX, HY, HZ | F(F, TX, TY, TZ)] 
     end, 
    G(G, D1, D2, D3) 
end,                    
Data1 = [<<5>>,<<6>>,<<7>>], 
Data2 = [<<5>>,<<6>>,<<7>>], 
Data3 = [<<5>>,<<6>>,<<7>>], 
F(Data1, Data2, Data3). 
[<<5>>,<<5>>,<<5>>,<<6>>,<<6>>,<<6>>,<<7>>,<<7>>,<<7>>] 

當然,你可以用lists模塊做到這一點:

lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)). 
[<<5>>,<<5>>,<<5>>,<<6>>,<<6>>,<<6>>,<<7>>,<<7>>,<<7>>] 
+1

感謝,作品像一個魅力 – BAR 2010-08-14 17:13:38

2

您可以編寫自定義zip函數來完成此操作。

zip([HX | TX], [HY | TY], [HZ | TZ]) -> [[HX, HY, HZ] | zip(TX, TY, TZ)]; 
zip([], [], []) -> []. 

只要輸入的長度相同,此功能就可以正常工作。處理不同長度的輸入將需要一些修補。事情是這樣的:

zip(X, Y, Z) when length(X) =:= 0; length(Y) =:= 0; length(Z) =:= 0 -> []; 
zip([HX | TX], [HY | TY], [HZ | TZ]) -> [[HX, HY, HZ] | zip(TX, TY, TZ)]. 

叫它這樣的:

7> my_module:zip(Data1, Data2, Data3). 
[[<<5>>,<<5>>,<<5>>], 
[<<6>>,<<6>>,<<6>>], 
[<<7>>,<<7>>,<<7>>]] 

參見:標準庫函數lists:zip3

+0

您也可以使用列表:zipwith3避免自己編寫遞歸循環。 – cthulahoops 2010-08-13 14:12:55

+0

@cthulahoops:你會注意到我提到了'lists:zip3'。然而,OP需要列表列表而不是'zip3'生成的元組列表。因此推出了我自己的功能。我相信你可以將元組轉換爲列表。 – 2010-08-14 06:53:14

+0

我在想列表:zipwith3(fun(X,Y,Z) - > [X,Y,Z] end,Data1,Data2,Data3))處理元組/列表問題。 – cthulahoops 2010-08-14 23:29:40

0
Final = Data1 ++ Data2 ++ Data3. 
+1

我不認爲OP想要_concatenate_列表。你已經發布的代碼片段將產生'[<<5>>,<<6>>,<<7>>,<<5>>,<<6>>,<<7>>,<<5>>,<<6>>,<<7>>]'這是不是他所期待的'Final'是。 – 2010-08-13 09:50:24

+0

啊!你是對的。我完全錯過了交錯部分。 – ram 2010-08-13 10:00:57

0

這是我走的它。有了這個,您可以根據需要添加儘可能多的數據集,只需將它們添加到列表中即可。它還會考慮列表的大小是否不同。如果二進制數據可能很大或者它是一個非常常見的函數,那麼使用新的二進制模塊可能會更高效,而不是將二進制數據分解爲1字節的列表。

-module(zippy). 
-compile(export_all). 

zipAll(L) -> zip({L,[]}). 
zip({L,Final}) -> 
    case lists:any(fun(X) -> case X of [] -> false; _ -> true end end,L) of 
     true -> zip(lists:mapfoldl(fun x/2,Final,L)); 
     _ -> lists:reverse(Final) 
    end. 

x([],L) -> {[],[null|L]}; 
x([H|T],L) -> {T,[H|L]}. 

start() -> 
    Data1 = [<<5>>,<<6>>,<<7>>], 
    Data2 = [<<5>>,<<6>>,<<7>>], 
    Data3 = [<<5>>,<<6>>,<<7>>], 
    Data4 = [<<5>>,<<6>>,<<7>>,<<1>>], 
    zipAll([Data1,Data2,Data3,Data4]). 

你想列表內涵 [{X,Y,Z}的|| X < -Data1,Y < -Data2,Z < -Data3]] 這更多地生成訂單無關緊要的所有可能性。