2016-12-12 76 views
0

Elixir和函數編程的新手我有一些問題需要從這個結構中獲取「品味」鍵。Elixir從json獲取鍵/值對/ struct

json = response.body 
icecream = Poison.decode!(json, as: %{"items" => [%Icecream{}]}) 

Returns: 
[%{"items" => [%MyModule.Icecream{size: "Large", 
taste: "Pistachio"}]}] 

我想僅以最優化的方式將味道(「開心果」)保存到變量中。

我期待着開悟。 :)

解決方案: 我想出了這個自己:

taste = List.first(icecream["items"]).taste 
+0

您應該選擇的方法取決於您希望邊緣案例的方式。當元素不在那裏時你想要發生什麼(如果你在處理這種情況)?你希望它提出異常還是返回nil?還有別的嗎? –

+0

我希望它永遠在那裏,但我同意用它檢查會更好。 – Zahrec

回答

2

使用的管道,你可以做

icecream |> hd |> Map.get("items") |> hd |> Map.get(:taste) 

不過,我建議你結合使用get_in/2Access helpers,其中IMO會產生非常可讀的代碼,並且對於更復雜的情況看起來更好。

import Access 
get_in icecream, [at(0), key!("items"), at(0), key!(:taste)] 
+0

感謝您的回答。我在第二個解決方案上遇到編譯器錯誤:未定義的函數在/ 1 – Zahrec

+0

您是否導入Access?如果你擔心混亂你的名字空間,你也可以在本地執行一個函數。 –

+1

@PatrickOscity僅在特定版本的Elixir中可用嗎?也許Zahrec正在使用舊版的Elixir? –

0

你也可以使用一個簡單的模式匹配:

[%{"items" => [%{taste: taste_val}]}] = your_result 

它節省了taste值到一個變量taste_val。如果您的結果沒有taste,那麼在您使用定義結構的defstruct模塊時,它將被設置爲nil(或您的默認值)。

0

您還可以使用Map.getMap.fetch 請參見:https://hexdocs.pm/elixir/Map.html#fetch/2

請記住,如果你正在使用

Map.fetch!(map,key)

可以引起副作用(錯誤拋出)當鑰匙不存在於map中。如果您使用的是Map.fetch(map,key),您將返回一個元組,其中正確錯誤狀態,表示keymap中的可用性。