开发者

Erlang - Interleave the easy way

Whats the easy/efficient way of interleaving three data sets..

Data1 = [<<5>>,<<6>>,<<7>>],
Data2 = [<<5>>,<<6>>,<<7>&g开发者_开发百科t;],
Data3 = [<<5>>,<<6>>,<<7>>].

End Result:

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

Im sure its like

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


Module function:

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

Same in shell:

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

And of course you can do it with lists module:

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


You can write a custom zip function to accomplish this.

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

This function will work fine as long as the length of the inputs are the same. Dealing with inputs of varying length will take some tinkering. Something like this:

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

Call it thus:

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

See also: standard library function lists:zip3.


Final = Data1 ++ Data2 ++ Data3.


Here's my go at it. With this you can add as many Data sets as you want, just add them to a list. It also takes into account if the lists are different sizes. Probably more efficient to use the new binary module instead of breaking down the binary data into 1 byte lists if the binary data can be large or it's a very common function.

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

you're thinking of list comprehensions [{X,Y,Z} || X <-Data1, Y<-Data2,Z<- Data3]] which is more to generate all possibilities where order doesn't matter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜