2015-09-16 22 views
3

我有一個使用Ecto的結果列表。我想用一個關鍵字列表,我就可以使用來填充<select>鳳凰內結束了,但我不能確定如何把這個名單變成一個關鍵字列表一樣["1": "Author #1", "2": "Author #2"]在Elixir中的關鍵字列表列表

authors = Repo.all(Author) 
# How would I create ["1": "Author #1", "2": "Author #2"] 

回答

3

關鍵字列表需要原子作爲關鍵字。好消息是你不需要關鍵字列表給select。這裏有兩種方法:

  1. 查詢,直接就做:

    authors = Repo.all from a in Author, select: {a.name, a.id} 
    
  2. 做它的數據:

    authors = Repo.all Author 
    Enum.map(authors, fn a -> {a.name, a.id} end) 
    

的第一個優點是你只會從表中加載你需要的數據。

3

選擇只使用作者姓名Enum.map

authorNames = authors |> Enum.map(fn a-> a.name end) 

然後使用Enum.zip設置鍵值對

1..Enum.count(authors) |> Enum.map(fn x-> to_string(x) end) |> Enum.zip(authorNames) 

這將產生soemthing像:

[{"1", "Author #1"}, {"2", "Author #2"}] 

如果你希望它是你需要的第一個元素是一個原子,因爲關鍵字列表,只使用原子作爲鍵真正的關鍵字列表

1..Enum.count(authors) |> Enum.map(fn x-> x |> to_string |> String.to_atom end) |> Enum.zip(authorNames) 

這將產生

["1": "Author #1", "2": "Author #2"] 

但我一直聽說要仔細管理原子的數量,並且將大量的字符串轉換爲原子並不是最佳實踐。除非您知道您的查詢將返回多少個作者,否則在將密鑰數字轉換爲原子時可能需要小心。

+1

'[「1」:「作者#1」,「2」:「作者#2」]'是關鍵字列表。 ':「1」是一個原子。嘗試'[「1」:「作者#1」,「2」:「作者#2」] == [{:「1」,「作者#1」},{:「2」,「作者#2」 }]'在iex中。 –

+2

而不是使用'Enum.map'獲取名稱,您可以使用ecto:'Repo.all(from(a在作者中,選擇:a.name))'獲取名稱''。 –

+0

@ EricMeadows-Jönsson謝謝,我不是100%確定'[「1」:「作者#1」,「2」:「作者#2」]是什麼,但它仍然是關鍵字列表。我已經更新了我的答案以反映這一點 – Letseatlunch