gpt4 book ai didi

enumeration - Elixir - 循环并添加到 map

转载 作者:行者123 更新时间:2023-12-03 07:53:41 25 4
gpt4 key购买 nike

我正在用我在 C# 中构建的一些代码在 Elixir 中重建一些东西。

它被很好地结合在一起,但工作得很好(虽然不是在 Linux 上,因此重建)。

基本上它所做的是检查一些 RSS 提要,看看是否有任何新内容。这是代码:

Map historic (URL as key, post title as value).
List<string> blogfeeds
while true
for each blog in blogfeeds
List<RssPost> posts = getposts(blog)
for each post in posts
if post.url is not in historic
dothing(post)
historic.add(post)

我想知道如何在 Elixir 中有效地进行枚举。此外,我将东西添加到“历史”的过程似乎是反函数式编程。

显然,第一步是声明我的 URL 列表,但除此之外,枚举的想法让我很困惑。有人可以帮我吗?谢谢。

最佳答案

这是一个很好的挑战,解决它肯定会让你对函数式编程有一些了解。

函数式语言中此类问题的解决方案通常是reduce (通常称为 fold )。我将从一个简短的回答开始(而不是直接翻译),但请随时要求跟进。

以下方法通常不适用于函数式编程语言:

map = %{}
Enum.each [1, 2, 3], fn x ->
Map.put(map, x, x)
end
map

最后的映射仍然是空的,因为我们不能改变数据结构。每次打电话 Map.put(map, x, x) ,它将返回一个新 map 。所以我们需要在每次枚举后显式检索新 map 。

我们可以在 Elixir 中使用 reduce 来实现:
map = Enum.reduce [1, 2, 3], %{}, fn x, acc ->
Map.put(acc, x, x)
end

Reduce 将发出前一个函数的结果作为下一项的累加器。运行上面的代码后,变量 map将是 %{1 => 1, 2 => 2, 3 => 3} .

由于这些原因,我们很少使用 each在枚举上。相反,我们使用 the Enum module 中的函数,支持广泛的操作,最终回落到 reduce当没有其他选择时。

编辑:要回答问题并更直接地翻译代码,您可以这样做来检查和更新 map :
Enum.reduce blogs, %{}, fn blog, history ->
posts = get_posts(blog)
Enum.reduce posts, history, fn post, history ->
if Map.has_key?(history, post.url) do
# Return the history unchanged
history
else
do_thing(post)
Map.put(history, post.url, true)
end
end
end

事实上,在这里使用集合会更好,所以让我们重构它并在过程中使用集合:
def traverse_blogs(blogs) do
Enum.reduce blogs, HashSet.new, &traverse_blog/2
end

def traverse_blog(blog, history) do
Enum.reduce get_posts(blog), history, &traverse_post/2
end

def traverse_post(post, history) do
if post.url in history do
# Return the history unchanged
history
else
do_thing(post)
HashSet.put(history, post.url)
end
end

关于enumeration - Elixir - 循环并添加到 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29924170/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com