2016-10-11 19 views
1

是否有任何本地靈藥的方法允許我通過鍵從鍵值中獲取值,不管鍵是原子還是字符串?像:如何通過map中的鍵獲取值,不管 - 鍵是字符串還是原子?

a = %{ k: 1 } 
b = %{ "k" => 1 } 

pure_elixir_method(a, :k) => 1 
pure_elixir_method(b, :k) => 1 
+0

很確定沒有。 – Dogbert

+0

爲什麼不使用'Map.get(map,to_string key)'?給予字符串時'to_string'的行爲與標識函數相同。 – helios35

+5

你認爲這種方法返回'%{k:1,「k」=> 2}'是什麼? – mudasobwa

回答

3

那麼,所需的行爲可能與定義的特定protocol來實現:

defprotocol IndifferentAccess do 
    def get(data, key) 
end 

defimpl IndifferentAccess, for: Map do 
    def get(data, key) when is_binary(key) do 
    case Map.fetch(data, key) do 
     {:ok, value} -> value 
     :error -> 
     case Map.fetch(data, String.to_atom(key)) do 
      {:ok, value} -> value 
      :error -> :error 
     end 
     end 
    end 
    end 
    def get(data, key) when is_atom(key) do 
    case Map.fetch(data, key) do 
     {:ok, value} -> value 
     :error -> get(data, Atom.to_string(key)) 
    end 
    end 
end 

a = %{ k: 1 } 
b = %{ "k" => 1 } 
a |> IndifferentAccess.get(:k) 
#⇒ 1 
b |> IndifferentAccess.get(:k) 
#⇒ 1 

但我不會那樣做。

2

沒有一個。

但是你可以寫自己的包裝方法,這樣做:

defmodule MyMap do 
    def get(map, key) when is_atom(key) do 
    Map.get(map, key) || Map.get(map, to_string(key)) 
    end 
end 

使用方法如下:

map = %{:a => 1, "b" => 2} 

MyMap.get(map, :a)  # => 1 
MyMap.get(map, :b)  # => 2 

1.因爲你可以,沒有按」你的意思是你應該。 %{k: 1, "k" => 2}是一個很好的例子,爲什麼你不應該這樣做(特別是對於你不知道的數據)。

2.此方法僅適用於​​關鍵參數,可以因此接受Atom和字符串參數進行修改:MyMap.get(map, "a") # => 1

3.如果你很喜歡得到映射值使用原子,在開始時考慮象徵你的地圖的鍵。看我的ExUtils.Map.symbolize_keys/2。如果你想自己實現它,你可以get the code here

相關問題