作爲Elixir的新手,我在理解模式匹配方面存在一些問題。使用Elixir獲取地圖列表中的特定關鍵值?
如果我有一個花好月圓的數據結構是這樣的:
list_with_maps = [%{"id" => 1, "name" => "a"}, %{"id" => 2, "name" => "b"}]
什麼將擺脫所有ID字段的值的最佳方式?
作爲Elixir的新手,我在理解模式匹配方面存在一些問題。使用Elixir獲取地圖列表中的特定關鍵值?
如果我有一個花好月圓的數據結構是這樣的:
list_with_maps = [%{"id" => 1, "name" => "a"}, %{"id" => 2, "name" => "b"}]
什麼將擺脫所有ID字段的值的最佳方式?
可以映射在列表並返回使用Enum.map/2
Enum.map(list_with_maps, fn (x) -> x["id"] end)
[1, 2]
的ID可以使用capture運營商寫相同的功能:
Enum.map(list_with_maps, & &1["id"])
我寧願寫& &1["id"]
爲&(&1["id"])
,但括號是可選的。
爲了完整性的答案對這個問題,你也可以做這樣的事情:
defmodule Test do
def get_all_ids([head | tail ]) do
IO.puts head["id"]
get_all_ids(tail)
end
def get_all_ids([]) do
IO.puts "end"
end
end
這會像這樣使用:
iex(7)> Test.get_all_ids(list_with_maps)
1
2
end
:ok
雖然我覺得@ Gazler的答案是在這種情況下更好的答案。
哦,既然你特別提到模式匹配,這也將工作:
defmodule Test do
def get_all_ids([%{"id" => id} = m | tail ]) do
IO.puts id
get_all_ids(tail)
end
def get_all_ids([]) do
IO.puts "end"
end
end
的調用將是完全一樣的;第二種方法的區別在於它使用模式匹配來解析參數列表中的地圖。
也可能要更改參數列表在此行中:def get_all_ids([%{"id" => id} = m | tail ]) do
這個:def get_all_ids([%{"id" => id} = _m | tail ]) do
只是爲了避免該警告有關m
未被使用。
Map
的鍵的子集的
一個更通用的(和更簡單)的方法是使用Map.take/2
,您可以使用這樣的:
map = %{"id" => 1, "name" => "a"}
Map.take(map, ["id"])
> %{"id" => 1}
正如你所看到的,它需要一個數組的鍵,並返回一個只包含你想要的鍵的新地圖。
現在,將其應用於列表與使用地圖一樣簡單,然後在mapper函數中使用Map.take/2
。正如已經指出的那樣,你可以做到這一點使用一個拉姆達:
Enum.map(list_with_maps, fn (map) -> Map.take(map, ["id"]) end)
或者你可以使用一個捕獲:
Enum.map(list_with_maps, &(Map.take(&1, ["id"])))
這將創造更多的中間地圖,但是對於贏得」大多數情況下, T爲一個問題,因爲藥劑是非常聰明的記憶重新使用,也不會真正創建這些對象很多次,unles
從地圖列表中提取的名稱值
names = for %{name: n, id: _} <- list_with_maps, do: n