假设有一个列表的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.
答案 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).
这个列表库太酷了.. :))