我想编写一个函数来用输入列表中的给定原子替换特定原子。但我想使用模式匹配而不是使用条件语句来实现。有什么想法吗?
我还想编写一个函数来返回表达式中的唯一原子。 e.g。
输入:
[a, b, c, a, b]
输出:
c
输入:
[b, b, b, r, t, y, y]
输出:
[t, r]
答案 0 :(得分:1)
假设您要替换所有实例并保持列表的顺序(适用于所有术语):
replace(Old, New, List) -> replace(Old, New, List, []).
replace(_Old, _New, [], Acc) -> lists:reverse(Acc);
replace(Old, New, [Old|List], Acc) -> replace(Old, New, List, [New|Acc]);
replace(Old, New, [Other|List], Acc) -> replace(Old, New, List, [Other|Acc]).
对于唯一元素过滤器,您需要保持已查看的元素的状态。
在函数头中仅使用模式匹配来实现这样的函数真的很尴尬,你不会从中获得任何(性能)。尴尬来自于必须遍历所讨论的列表和保持已解析元素状态的列表。你也会失去很多可读性。
我建议选择更简单的东西(适用于所有术语,而不仅仅是原子):
unique(List) -> unique(List, []).
unique([], Counts) ->
lists:foldl(fun({E, 1}, Acc) -> [E|Acc];
(_, Acc) -> Acc
end, [], Counts);
unique([E|List], Counts) ->
unique(List, count(E, Counts).
count(E, []) -> [{E, 1}];
count(E, [{E, N}|Rest]) -> [{E, N + 1}|Rest];
count(E, [{X, N}|Rest]) -> [{X, N}|count(E, Rest)].
答案 1 :(得分:0)
我正在寻找解决你的第一个问题的一种方法是使用警卫而不是if语句。仅使用模式匹配似乎不可能(或者即使您可以这样做也是可取的)。
因此,例如,您可以执行以下操作:
my_replace([H|T], ToReplace, Replacement, Accum) when H == ToReplace ->
my_replace(T, ToReplace, Replacement, [Replacement|Accum]);
my_replace([H|T], ToReplace, Replacement, Accum) ->
my_replace(T, ToReplace, Replacement, [H|Accum]);
my_replace([], ToReplace, Replacement, Accum) ->
lists:reverse(Accum).
编辑:为了简单和风格而编辑,感谢您的评论。 :)
对于你问题的第二部分,你认为什么是“表达”?
编辑:没关系,usort并没有完全删除重复项,抱歉。