2010-08-13 17 views
5

¿Cuál es el camino más fácil/eficiente de entrelazado de tres conjuntos de datos ..Erlang - Intercalar el camino más fácil

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

Resultado Final:

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

Estoy seguro de que su gusto

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

Respuesta

2

de función del módulo:

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

mismo con cáscara:

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

Y por supuesto, puede hacerlo con lists módulo:

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

Gracias que funciona como un encanto – BAR

2

Puede escribir una función personalizada zip para lograr esto.

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

Esta función funcionará bien siempre que la longitud de las entradas sea la misma. Tratar con entradas de diferente duración requerirá algunos retoques. Algo como esto:

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

llamada así:

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

Consulte también: función de la biblioteca estándar lists:zip3.

+0

También podría usar listas: zipwith3 para evitar escribir usted mismo el bucle recursivo. – cthulahoops

+0

@cthulahoops: Notarás que mencioné 'lists: zip3'. Sin embargo, el OP quería una lista de listas en lugar de la lista de tuplas que produce 'zip3'. Por lo tanto rodó mi propia función. Sin embargo, estoy seguro de que puedes convertir las tuplas en listas. –

+0

Estaba pensando en listas: zipwith3 (diversión (X, Y, Z) -> [X, Y, Z] final, Datos1, Datos2, Datos3)) que trata el problema de la tupla/lista. – cthulahoops

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

No creo que el OP quiera _concatar_ listas. El fragmento de código que has publicado producirá '[<<5>>, <<6>>, <<7>>, <<5>>, <<6>>, <<7>>, <<5>>, <<6>>, <<7>>]' que no es lo que él espera 'Final' ser. –

+0

¡Ah! Tienes razón. Me perdí totalmente la parte de entrelazado. – ram

0

Aquí está mi ir a eso. Con esto puedes agregar tantos conjuntos de datos como quieras, solo agrégalos a una lista. También toma en cuenta si las listas son de diferentes tamaños. Probablemente sea más eficiente usar el nuevo módulo binario en lugar de descomponer los datos binarios en listas de 1 byte si los datos binarios pueden ser grandes o una función muy común.

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

que está pensando en las listas por comprensión [{X, Y, Z} || X < -Data1, Y < -Data2, Z < - Data3]] que es más para generar todas las posibilidades donde el orden no importa.

Cuestiones relacionadas