2017-07-26 6 views
2

のリストから情報を取得し、私はポストを経由して私に送られている。この構造:基本的には、各連絡先は私がリストを作成しようとしているマップname => phone_numbersエリクサーはマップ

いると連絡先のリストであるcontacts = [%{"John" => ["0724573977"]}, %{"Mary" => ["0724573111", "0744556778"]}]

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 

この1つが生成します:奇数であるが、私は私が間違っているのかわからない[[[["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)に一致する関数節はerl_evalと一致しません。 " - insi "/ 1' –

+0

@RomeoMihalcea私が逃したものを見る(マップのリストであるという事実) - それに応じてコードを更新しました – bitwalker

3

1が使用する番号のリストだけを取得するには:

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

へ名前を数字に置き換えると、チェーンの途中でEnum.with_indexが使用される可能性があります。

5

あり、すでに掲載多くの正解がありますが、私は、私は私の好みのソリューションを投稿しようと思いました:3 <-forを使用します。

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

関連する問題