Erlang列表与元组比较

时间:2012-12-07 14:38:56

标签: functional-programming erlang

假设有一个列表的erlang列表:

请注意,列表的大小是固定的。在这种情况下3.

A = [[1,2,3],[4,5,6],[1,8,3],[1,9,3]]

我正在尝试编写将删除[1,_,3]形式的所有元素的函数。 所以我的预期输出格式为:[[4,5,6]]

我能想到的一个解决方案是列表:dropwhile()可以使用的函数。

我在构造谓词函数时遇到了麻烦。是否更容易将每个元素转换为元组然后进行比较?如果是这样,我没有正确的方法可以省略中间元素。

你能帮我解决一下吗?任何其他有效的方法也将受到高度赞赏。

提前致谢!

编辑: 问题扩展:

假设两个列表的列表:

A = [[1,2,3],[2,3,4],[4,5,6]]

B = [[1,4,3],[4,7,6],[7,8,9],[4,9,7],]

输出F(A,B)= [[7,8,9],[4,9,7]]

F被定义为函数,其从列表B中移除与第一和第三位置中的列表A中的任何一个元素匹配的所有元素。

在这种情况下,列表B中匹配[1,_,3]或[2,_,4]或[4,_,6]的所有元素将从列表中删除,以给出结果列表。

我很难写F.

3 个答案:

答案 0 :(得分:12)

您的过滤功能需要一些帮助:

lists:filter(fun([1, _, 3]) -> false; (_) -> true end,
             [[1,2,3],[4,5,6],[1,8,3],[1,9,3]]).

您需要在功能头中进行匹配才能使其正常工作。


至于有多个过滤器,你可以使用一个乐趣图(未经测试):

composed_filter(Tests, Input) ->
  lists:filter(fun(X) -> lists:all([F(X) || F <- Tests]) end,
               Input).

要使用多个过滤器,您可以执行以下操作:

filter(fun([1,_,3]) -> true;
          ([5,_,7]) -> true;
          ([9,_,13]) -> true;
          (_) -> false end, Input)
% or
composed_filter([fun([1,_,3]) -> true; (_) -> false end,
                 fun([5,_,7]) -> true; (_) -> false end,
                 fun([9,_,13]) -> true; (_) -> false end],
                Input)

虽然除非你需要可编程动态可组合性,否则你应该只使用第一个。另一种方法,再次是使用函数运行合成而不是使用专门的composition_filter。这是Haskell人群喜爱的更加组合式的方法。请注意,上述功能略有不同。第一个具有orelse语义,而后者具有andalso语义。在第一种情况下,如果一个或多个模式匹配,则获取元素,而在后一种情况下,如果 all 模式/符号匹配,则只获得结果。您可以使用lists:any/2获取composed_any_filter

答案 1 :(得分:3)

dropWhile只能返回列表的前缀,所以它不起作用。请改用filter

答案 2 :(得分:1)

我设法为扩展问题找到了解决方案:

鉴于A和B的问题:

F(A,B) ->
    lists:filter(fun(X) -> predicate(X,B) end, A).

predicate(X, B) ->
    Xr = lists:delete(lists:nth(2,X),X),
    Br = lists:map(lists:delete(lists:nth(2,Y),Y),B),
    lists:member(Xr, Br).

这个列表库太酷了.. :))