2017-07-26 111 views
2

我有這個結構的列表信息被通過郵寄方式發送給我:contacts = [%{"John" => ["0724573977"]}, %{"Mary" => ["0724573111", "0744556778"]}]這基本上是每個接觸地圖name => phone_numbers藥劑正從地圖

我試圖與一個列表中的聯繫人列表所有的電話號碼,忽略任何名字,只是一個數字的列表:

a = [%{"1" => ["0724573977"]}, %{"2" => ["0724573111", "0744556778"]}] 

p = Enum.reduce a, [], fn(contact, acc) -> 
    for {_record_id, phones} <- contact do 
     for phone <- phones do 
      acC++ phone 
     end 
    end 
end 

IO.inspect p 

這其中產生:[[[["0724573977"] | "0724573111"], [["0724573977"] | "0744556778"]]]這是奇怪的,但我不知道我做錯了。

回答

2

這可能不是慣用的藥劑,因爲我是新來的語言,但是這對我的作品:

iex(11)> List.flatten(Enum.map(a, fn(x) -> Map.values(x) end)) 
["0724573977", "0724573111", "0744556778"] 
+0

謝謝,更新。 –

2

簡單得多做:

a 
|> Enum.flat_map(&Map.to_list/1) 
|> Enum.flat_map(a, fn {_record_id, phones} -> phones end) 

與你試過雖然是的for每次迭代產生一個新的列表中的元素,另外因爲藥劑是不可變的,你是不是真正的代碼的問題更改acc您正在創建將每個電話號碼追加到同一個列表的元素,因此您最終得到的列表的意外列表。

+0

看起來很奇妙,但... **(FunctionClauseError)no函數子句匹配:erl_eval。「 - insi de-an-interpre-fun - 「/ 1' –

+0

@RomeoMihalcea我看到我錯過了(事實上它是一張地圖列表) - 我已經更新了相應的代碼 – bitwalker

3

要獲得只是一個數字的列表中的一個可能是:

contacts 
|> Enum.map(&Map.values/1) 
|> List.flatten 
#⇒ ["0724573977", "0724573111", "0744556778"] 

要用數字替換名字,可以在鏈的中間使用Enum.with_index

5

有許多正確的答案已經發布,但我想我會後我的首選解決方案:使用:

iex(1)> contacts = [%{"1" => ["0724573977"]}, %{"2" => ["0724573111", "0744556778"]}] 
[%{"1" => ["0724573977"]}, %{"2" => ["0724573111", "0744556778"]}] 
iex(2)> for contact <- contacts, {_, phones} <- contact, phone <- phones, do: phone 
["0724573977", "0724573111", "0744556778"] 

(我不喜歡特別基於List.flatten/1解決方案,因爲他們將無法正常工作如果最後一級的數據是一個列表而不是一個字符串,那麼同樣的方法也可以這樣做,這個函數在任何深度都展平了每一個列表,儘管這個特殊情況並不重要,但是因爲你的最後一級數據是一串字符串。)

+0

這是迄今爲止最好的解決方案,應該標記爲正確的答案。 @RomeoMihalcea請注意爲什麼'List.flatten/1'應該在與確定結構一起使用時通常避免的解釋。 – mudasobwa