Erlang:检查重复的插入元素
Posted
技术标签:
【中文标题】Erlang:检查重复的插入元素【英文标题】:Erlang: check duplicate inserted elements 【发布时间】:2016-06-27 19:02:00 【问题描述】:我想知道插入的元素是否重复。
这是我正在寻找的简单示例:
第一次运行应该返回 false。
check_duplicate("user", "hi").
但在第二次运行时应该返回 true。
check_duplicate("user", "hi").
【问题讨论】:
你的问题对我来说没有意义。你的例子正确吗? @PeerStritzinger 嗨,我不太了解 Erlang。但我的问题是如何将重复的插入元素捕获到函数中。就像如果我使用相同的插入元素(“user”,“hi”)两次运行此函数 check_duplicate(“user”,“hi”),它应该返回 True。谢谢。 @Mr.zero,将元素插入集合。并通过功能检查erlang.org/doc/man/sets.html#is_element-2 @Atomic_alarm 嗨,你能举个简单的例子吗?我不太了解 Erlang。谢谢。 不,这只是建议。我也不明白你具体需要什么。 【参考方案1】:函数式编程的最佳特性之一是纯函数。甚至还有像 Haskell 这样的函数式语言,你不能编写不纯的函数。纯函数总是为相同的参数返回相同的值。不纯函数具有副作用,并且可以为相同的参数返回不同的结果。这意味着必须更改一些您无法将其视为函数参数的状态。你只是为了它。 Erlang 允许你这样做。你有很多选择如何做到这一点。最干净的是发送消息并从另一个进程接收消息。 (无论如何它是不纯的,但在 Erlang 中是惯用的。以下代码非常简单,不适合生产使用。您应该使用 OTP 行为和设计原则。)
has_dupes(Jid, Text) ->
Ref = make_ref(),
seen ! Ref, self(), Jid, Text,
receive Ref, Result -> Result end.
start_seen() ->
spawn(fun()-> register(seen, self()), loop_seen([]) end).
loop_seen(Seen) ->
receive Ref, From, Term ->
case lists:member(Term, Seen) of
true ->
From ! Ref, true,
loop_seen(Seen);
false ->
From ! Ref, false,
loop_seen([Term|Seen])
end
end.
另一种是从ets(Erlang Term Storage)中存储和读取。
has_dupes(Jid, Text) ->
(catch ets:new(seen, [set, named_table])),
not ets:insert_new(seen, Jid, Text).
但有一个问题。该表由进程拥有,并在进程终止时被删除。它的名字是全局的等等。另一个更脏的方法是从进程字典中存储和读取值。
has_dupes(Jid, Text) ->
case get(Jid, Text) of
undefined ->
put(Jid, Text, seen),
false;
seen ->
true
end.
但这很讨厌,你几乎不应该使用这样的代码。在大多数情况下,您应该使用显式状态
new_seen() -> [].
has_dupes(Jid, Text, Seen) ->
Term = Jid, Text,
case lists:member(Term, Seen) of
true -> true, Seen;
false -> false, [Term|Seen]
end.
这是大多数时候最好的解决方案,因为它是一个纯函数。当您需要查看更多术语时,您可以使用更好的数据结构,例如 sets
和 maps
,以获得更好的性能。
【讨论】:
抱歉迟到了我知道我对你的回答的问题迟到了(再次抱歉)。但在最后一个例子中 has_dupes(Jid, Text, Seen) ->.应该在这里看到什么?非常感谢。 @Mr.zero:Seen
是一个状态,在本例中是列表,但也可以是地图、集合……我已在答案中添加了构造函数。以上是关于Erlang:检查重复的插入元素的主要内容,如果未能解决你的问题,请参考以下文章