簡體   English   中英

循環遍歷值列表,在鍵中查找匹配項並在 Elixir 中對匹配值求和

[英]Loop through a list of values, find matches in keys and sum matched values in Elixir

我正在學習 Elixir 並且我在解決這個簡單問題時遇到了困難:

我有一個值列表:

my_list = ["a", "b", "c", "y", "z", "a", "e"]

我有一個 map:

my_map = %{"a" => -1, "b" => 0, "c" => 1, "d" => 2, "e" => 3}

我想遍歷my_list ,在 my_map 中找到所有關鍵事件,如果發生,則對my_map中的值my_map

在上面的示例中,它應該返回 2,因為:

-1 + 0 + 1 + (ignored) + (ignored) - 1 + 3

# => 2

在具有可變變量的語言中,這是一件非常容易做到的事情(我們可以循環列表並添加一個計數器)。 我正在努力改變我的心態。

謝謝你的幫助!

我正在努力改變我的心態。

令人欽佩。 如果您願意改變思維方式並嘗試更實用地思考,您會在 Elixir 中獲得巨大成功。 考慮到這一點,讓我們分解問題。

我想遍歷my_list

更准確地說,您想對列表中的每個元素執行某些操作並獲得結果列表。 那是Enum.map/2

Enum.map(my_list, fn x -> ...)

現在, ...需要替換為我們想要對每個列表元素執行的操作。 我們要獲取對應的 map 個元素,忽略那些不存在的。 由於我們要求和,“忽略”實際上只是意味着“替換為零”。 Map.get/3可以從 map 獲取一個值,如果沒有提供則使用默認值。

Enum.map(my_list, fn x -> Map.get(my_map, x, 0) end)

現在,我們有一個數字列表。 我們只想要總和。 這可以根據Enum.reduce/3來完成,但求和是一項足夠常見的任務,它有自己的 function: Enum.sum/1

Enum.sum(Enum.map(my_list, fn x -> Map.get(my_map, x, 0) end))

最后,這是倒着讀的。 它說“對列表映射的結果求和”,當它讀起來更清晰時“獲取列表,從 map 中獲取元素,然后求和”。 我們可以用pipe 接線員清理它。 下面的和上面的是等價的。

my_list |> Enum.map(fn x -> Map.get(my_map, x, 0) end) |> Enum.sum

這是一個很好的理解用例:

for key <- my_list, val = my_map[key], reduce: 0 do
  acc -> acc + val
end

這里的val = my_map[key]是一個過濾器。 key不在my_map中時,結果將為nil ,這是一個虛假值,因此被跳過。

雖然這里給出的兩個答案都是完全有效的,但為了完整起見,我將使用普通遞歸發布另一個答案。

defmodule Summer do
  def consume(list, map, acc \\ 0) # head

  def consume([], _, acc), do: acc # exhausted
  def consume([h | t], map, acc) when is_map_key(map, h),
    do: consume(t, map, acc + Map.fetch!(map, h))
  def consume([_h | t], map, acc), do: consume(t, map, acc)
end

Summer.consume my_list, my_map
#⇒ 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM