2012-06-21 4 views
6

Реализовать понимание списка Erlang, которое берет два элемента из списка и создает новый список списков.Erlang: как реализовать понимание списка Erlang?

У меня есть этот код

pair([], Acc) -> lists:reverse(Acc); 

pair(L, Acc0) -> 
    [ A, B | T ] = L, 
    Acc = [ [A, B] | Acc0 ], 
    pair(T, Acc). 

, который работает отлично:

7> l:pair(lists:seq(1,6), []). 
[[1,2],[3,4],[5,6]] 

но мне кажется, что я должен быть в состоянии осуществить это в качестве списка понимания. Мой Erlang-fu слишком слаб, чтобы придумать это.

Любые предложения?

Благодаря

ответ

1

список понимание будет неуклюжим, потому что он неизбежно должен сделать что-то для каждый элемент списка. Чтобы создать понимание списка, вы должны, таким образом, попытаться выяснить, является ли это четным или нечетным элементом, с которым вы разговариваете. Вот идея о том, что я говорю о:

pair(L) -> 
    L2 = lists:zip(lists:seq(1, length(L)), L), 
    [[A, B] || {Ai, A} <- L2, {Bi, B} <- L2, 
      Ai rem 2 == 1, Bi rem 2 == 0, Ai + 1 == Bi]. 

Временная сложность на этом, наверное, ужасно, потому что, насколько я знаю, Erlang не оптимизирует это в любом случае.

Я не думаю, что что-то не так с вашей функцией, и вы должны придерживаться ее.

8

Нет, понимание списка не было бы хорошим способом сделать это, по определению они работают только с одним элементом a. В вашем коде нет необходимости использовать аккумулятор, разница в скорости мала, here, и без него становится понятнее. Думаю, по крайней мере.

pairs([A,B|L]) -> 
    [[A,B]|pairs(L)]; 
pairs([]) -> []. 
+1

Это следует за мантрами Эрланг «пусть это сбой», например. для случая '[a]'. – Tilman

+0

@Tilman Да, функция ** определена ** для принятия пар элементов, поэтому, если это ошибка, если в списке есть нечетное число элементов. Конечно, вы всегда можете определить, что должно произойти в этом случае, и обработать его после этого. – rvirding

Смежные вопросы