2010-08-13 42 views
5

Che cosa è il modo più semplice/efficiente di interleaving tre insiemi di dati ..Erlang - Interleave il modo più semplice

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

Risultato finale:

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

Sono sicuro che la sua come

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

risposta

2

funzione Modulo:

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

Stesso in guscio:

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>>] 

E naturalmente è possibile farlo con lists modulo:

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

Grazie che funziona come un fascino – BAR

2

È possibile scrivere una funzione personalizzata zip per ottenere ciò.

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

Questa funzione funzionerà correttamente purché la lunghezza degli ingressi sia la stessa. Affrontare gli input di varia lunghezza richiederà un po 'di complicazioni. Qualcosa di simile a questo:

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)]. 

chiamata così:

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

Consulta anche: funzione di libreria standard lists:zip3.

+0

È inoltre possibile utilizzare le liste: zipwith3 per evitare di scrivere da soli il loop ricorsivo. – cthulahoops

+0

@cthulahoops: Noterai che ho menzionato 'lists: zip3'. Tuttavia, l'OP voleva un elenco di liste piuttosto che l'elenco di tuple prodotto da 'zip3'. Da qui ha rotolato la mia funzione. Sono sicuro che puoi convertire le tuple in liste. –

+0

Stavo pensando alle liste: zipwith3 (fun (X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) che tratta del problema della tupla/lista. – cthulahoops

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

Non penso che l'OP voglia _concatenare elenchi. Il frammento di codice che hai postato produrrà '[<<5>>, <<6>>, <<7>>, <<5>>, <<6>>, <<7>>, <<5>>, <<6>>, <<7>>]' che non è quello che si aspetta 'Final' di essere. –

+0

Ah! Hai ragione. Ho perso totalmente la parte interfogliata. – ram

0

Ecco il mio andare a esso. Con questo puoi aggiungere tutti i set di dati che desideri, basta aggiungerli a un elenco. Tiene anche conto se gli elenchi sono di dimensioni diverse. Probabilmente più efficiente usare il nuovo modulo binario invece di scomporre i dati binari in elenchi di 1 byte se i dati binari possono essere grandi o è una funzione molto comune.

-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]). 

stai pensando di list comprehension [{X, Y, Z} || X < -Data1, Y < -Data2, Z < - Data3]] che è più per generare tutte le possibilità in cui l'ordine non ha importanza.

Problemi correlati