Erlang - Interleave легкий путь - PullRequest
       4

Erlang - Interleave легкий путь

5 голосов
/ 13 августа 2010

Какой простой / эффективный способ чередования трех наборов данных ..

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

Ответы [ 4 ]

2 голосов
/ 13 августа 2010

Функция модуля:

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>>]
2 голосов
/ 13 августа 2010

Вы можете написать пользовательскую функцию 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 голосов
/ 14 августа 2010

Вот мой путь. При этом вы можете добавить столько наборов данных, сколько хотите, просто добавьте их в список. Он также учитывает, если списки имеют разные размеры. Возможно, более эффективно использовать новый двоичный модуль вместо разбиения двоичных данных на списки из 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]] это больше для создания всех возможностей, где порядок не имеет значения. </p>

0 голосов
/ 13 августа 2010
Final = Data1 ++ Data2 ++ Data3.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...