Erlang,将列表中的一个原子替换为另一个原子

Erlang,将列表中的一个原子替换为另一个原子,erlang,Erlang,我想编写一个函数,用输入列表中的给定原子替换特定原子。但是我想使用模式匹配而不是使用条件语句。有什么想法吗 我还想写一个函数,返回表达式中唯一的原子。 e、 g 输入: [a, b, c, a, b] [b, b, b, r, t, y, y] 输出: c [t, r] 输入: [a, b, c, a, b] [b, b, b, r, t, y, y] 输出: c [t, r] 我想要解决你的第一个问题的一种方法是使用警卫,而不是if语句。仅仅使用模式匹配

我想编写一个函数,用输入列表中的给定原子替换特定原子。但是我想使用模式匹配而不是使用条件语句。有什么想法吗

我还想写一个函数,返回表达式中唯一的原子。 e、 g

输入:

[a, b, c, a, b]   
[b, b, b, r, t, y, y]   
输出:

c
[t, r]
输入:

[a, b, c, a, b]   
[b, b, b, r, t, y, y]   
输出:

c
[t, r]

我想要解决你的第一个问题的一种方法是使用警卫,而不是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).
编辑:为简洁和风格而编辑,感谢您的评论。:)

对于你的问题的第二部分,你认为什么是“表达”?< /P>
编辑:不管怎样,usort不会完全删除重复项,对不起。

我想解决您的第一个问题的一种方法是使用防护,而不是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).
编辑:为简洁和风格而编辑,感谢您的评论。:)

对于你的问题的第二部分,你认为什么是“表达”?< /P>
编辑:不管怎样,usort不会完全删除重复项,抱歉。

假设您希望替换所有实例并保持列表的顺序(适用于所有术语):

对于“唯一元素”过滤器,需要保持已查看元素的状态

如果只在函数头中使用模式匹配来实现这样一个函数,那将非常尴尬,而且您将无法从中获得任何(性能)。尴尬之处在于必须循环遍历相关列表和保持已解析元素状态的列表。你也会失去很多可读性

我建议采用更简单的方法(适用于所有术语,而不仅仅是原子):


假设要替换所有实例并保持列表的顺序(适用于所有术语):

对于“唯一元素”过滤器,需要保持已查看元素的状态

如果只在函数头中使用模式匹配来实现这样一个函数,那将非常尴尬,而且您将无法从中获得任何(性能)。尴尬之处在于必须循环遍历相关列表和保持已解析元素状态的列表。你也会失去很多可读性

我建议采用更简单的方法(适用于所有术语,而不仅仅是原子):


你可以切换第一和第二个子句,删除“when H/=To_replace”-很明显,如果==不匹配,那么你不必替换该元素,也不要混合命名约定-To_replace很难看,To_replace很漂亮。是的,我对Erlang还是有点陌生,所以我还是有点摸索。谢谢意志edit@keymore:To_replace不是混合命名约定,因为对于原子、函数和模块,以及此类Erlang使用此_命名约定,如果您希望保持变量的此命名约定,并且仅大写第一个字母,这是一个品味问题(对于非Erlang读取器,请注意:这是由语言语法强制执行的)或者切换到cameltsyntax作为变量,其缺点是变量的命名约定与语言的其他部分完全不同。任何一种方法都是折衷的。顺便说一句,大多数Erlang代码都通过使用短的一个单词(或字母)varnames来避免这种命名方式,这是可以的,因为作用域只有一个函数,这些函数应该短,并且只设置一次也有帮助。您可以切换第一和第二子句并删除“when H/=To_replace”-很明显,如果==不匹配,则不必替换该元素也不要混合命名约定-替换很难看,替换很漂亮。是的,我对Erlang还是有点陌生,所以我仍然有点摸索。谢谢意志edit@keymore:To_replace不是混合命名约定,因为对于原子、函数和模块,以及此类Erlang使用此_命名约定,如果您希望保持变量的此命名约定,并且仅大写第一个字母,这是一个品味问题(对于非Erlang读取器,请注意:这是由语言语法强制执行的)或者切换到cameltsyntax作为变量,其缺点是变量的命名约定与语言的其他部分完全不同。无论如何,这两种方法都是折衷的。顺便说一句,大多数Erlang代码都通过使用短的一个单词(或字母)varnames来避免这种命名方式,这是可以的,因为范围只是一个功能,这些功能应该很短,并且只设置一次也很有帮助。把两个完全不同的问题作为一个问题问是很糟糕的形式。把两个完全不同的问题作为一个问题问是很糟糕的形式。