3

假设有一个 erlang 列表列表:

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

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

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

我可以考虑的一种解决方案是列表:dropwhile()可以使用的函数。

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

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

提前致谢!

编辑:问题扩展:

假设两个 erlang 列表列表:

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。

4

3 回答 3

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)

尽管除非您需要可编程的动态可组合性,否则您可能应该只使用第一个。另一种方法是使用函数而不是专门的composer_filter来运行组合。这是 Haskell 人群会喜欢的更加组合器风格的方法。请注意,上述功能略有不同。第一个具有orelse语义,而后者具有andalso语义。也就是说,在第一种情况下,如果一个或多个模式匹配,您将获得元素,而在后一种情况下,只有当所有模式/乐趣都匹配时,您才会获得结果。你可以lists:any/2用来获得一个composed_any_filter.

于 2012-12-07T15:52:21.013 回答
3

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

于 2012-12-07T14:57:10.213 回答
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).

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

于 2012-12-11T05:32:33.820 回答