假设有一个erlang列表:
请注意,列表的大小是固定的。在这种情况下3。
A = [[1,2,3],[4,5,6],[1,8,3],[1,9,3]]
我正在尝试编写函数,该函数将删除所有形式为[1,_,3]
的元素。所以我预期的输出形式是:[[4,5,6]]
我可以考虑的一个解决方案是可以使用的lists: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.
您的过滤功能需要一些帮助:
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)
尽管除非您需要可编程动态可组合性,否则您可能应该只使用第一个。另一种方法是使用函数运行组合,而不是使用专门的composed_filter。这是一种更具组合子风格的方法,Haskell人群会喜欢这种方法。请注意,以上功能略有不同。前者具有orelse
语义,而后者具有andalso
语义。也就是说,在第一种情况下,如果一个或多个模式匹配,则获得元素,而在后一种情况中,只有当所有模式/函数匹配时,才获得结果。您可以使用lists:any/2
来获得composed_any_filter
。
dropWhile
只能返回列表的前缀,所以它不起作用。请改用filter
。
我设法想出了一个扩展问题的解决方案:
给定有问题的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).
这个列表库太酷了..:)