вопрос фильтра списка erlang - PullRequest
       8

вопрос фильтра списка erlang

1 голос
/ 23 февраля 2011

У меня есть список - Sep1:

[
   ....
   ["Message-ID", "AAAAAAAAAAAAAAAAAAA"],
   ["To", "BBBBBBBBBBBBBBBBB"]
   ...
]

Я пытаюсь получить элемент, где первый элемент = Message_ID, например:

lists:filter(fun(Y) -> (lists:nth(1,lists:nth(1,Y)) =:= "Message-ID") end, Sep1).

Но я получаю ошибку:

 exception error: no function clause matching lists:nth(1,[])

 in function  utils:'-parse_to/1-fun-1-'/1

 in call from lists:'-filter/2-lc$^0/1-0-'/2

Но если я:

io:format(lists:nth(1,lists:nth(1,Sep1))).
> Message-ID

Что не так?

Спасибо.

Ответы [ 5 ]

5 голосов
/ 23 февраля 2011

Лучше изменить представление на [{Key, Value}, ...], чтобы вы могли использовать списки: ключ * функции, проплисты модуль или преобразовать его в dict с помощью ДИКТ:. from_list / 1

Но если вы все еще хотите использовать lists: filter / 2 , вы можете отфильтровать список списков по первому элементу следующим образом:

lists:filter(fun ([K | _]) -> K =:= "Message-ID" end, ListOfLists).

Если вы хотите извлечь хвосты списков, первый элемент которых соответствует «Message-ID», вы можете использовать понимание списка :

[Tail || ["Message-ID" | Tail] <- ListOfLists].
3 голосов
/ 23 февраля 2011

Что вам, вероятно, нужно, это:

[B || [A,B|_] <- L, A =:= "Message-ID"].

Это не предполагает никакой длины вложенных списков:

Возвращает список вторых элементов всех внутренних списков, чьипервый элемент - «Message-ID»

Если вы уверены, что существует только один «Message-ID» и хотите выдать ошибку, иначе:

[X] = [B || [A,B|_] <- L, A =:= "Message-ID"].

Если вы хотите только первыйодин (по-прежнему выдает ошибку, когда ее нет):

[X|_] = [B || [A,B|_] <- L, A =:= "Message-ID"].

Чтобы понять, что этот код делает, я рекомендую прочитать официальную документацию по Erlang о списках и главе Erlang Learn You Some aboutпо той же теме: Список понятий .

3 голосов
/ 23 февраля 2011

Почему вы используете два вложенных lists:nth вызова?

lists:filter(fun(Y) -> lists:nth(1, Y) =:= "Message-ID" end, Sep1) работает для меня и возвращает список, содержащий элементы, которые вы хотите (списки, где первый элемент - "Message-ID").Просто сопоставьте шаблон в этом списке, чтобы получить нужный элемент, например, если вы хотите только один такой элемент, вы можете сделать:

case lists:filter(fun(Y) -> lists:nth(1, Y) =:= "Message-ID" end, Sep1) of
  [Result] -> % do something with it;
  [] -> % no such element found
end
1 голос
/ 23 февраля 2011

Предполагая, что ваш список содержит только элементы, каждый из которых имеет 2 элемента, вы можете использовать списки, выполняя что-то вроде этого:

1> L = [["Message-ID","AAAAAAAA"],["To","BBBBBBBBBBB"]].
[["Message-ID","AAAAAAAA"],["To","BBBBBBBBBBB"]]
2> [[A,B]||[A,B] <- L, A =:= "Message-ID"].
[["Message-ID","AAAAAAAA"]]

Надеюсь, это поможет.

0 голосов
/ 23 февраля 2011

Вы можете создать свой собственный фильтр (который не заботится о количестве элементов):

    filter(List) -> filter(List,[]).

    filter([],Acc) -> lists:reverse(Acc);
    filter([[]|Tail],Acc) -> filter(Tail,Acc);
    filter([[H|T]|Tail],Acc) ->
      case H =:= "Message-ID" of
        true -> filter(Tail,[[H|T]|Acc]);
        _ -> filter(Tail,Acc)
      end.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...