erlang列表过滤器问题

时间:2011-02-23 16:57:24

标签: list filter erlang

我有清单 - 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 个答案:

答案 0 :(得分:5)

最好将表示更改为[{Key, Value}, ...],以便您可以使用lists:key*函数,proplists模块,或使用dict将其转换为dict:from_list/1

但如果您仍想使用lists:filter/2,可以按第一个元素过滤列表列表,如下所示:

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

如果要提取第一个元素与“消息ID”匹配的列表尾部,可以使用list comprehensions

[Tail || ["Message-ID" | Tail] <- ListOfLists].

答案 1 :(得分:3)

为什么要使用两个嵌套的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

答案 2 :(得分:3)

你可能想要的是:

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

这不假设嵌套列表的任何长度:

它将返回所有内部列表的第二个元素的列表,其第一个元素是“Message-ID”

如果您确定只有一个“消息ID”,并且想要抛出错误,那么:

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

如果你只想要第一个(当没有时仍然抛出错误):

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

为了理解这段代码的作用,我建议您阅读official Erlang documentation关于列表推导的内容以及关于同一主题的“了解一些Erlang”一章:List Comprehensions

答案 3 :(得分:1)

假设你的列表只包含每个元素包含2个元素的元素,你可以使用list comprehension做这样的事情:

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

希望这有帮助。

答案 4 :(得分:0)

您可以创建自己的过滤器(不关心元素的数量):

    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.