Elixir:如何播种地图?

时间:2018-04-17 20:23:28

标签: elixir

我想在Elixir中生成一个地图:

  [1: 1, 1: 2, 1: 3, 2: 1, ..... , 3: 3]

以下是代码:

  n = 3
  map = %{ 0, 0}
  for x <- 1..n do
    for y <- 1..n do
      map = %{map | x, y}
    end
  end

此代码编译但运行时只有原始(0:0)条目?如何使用递归数字成功附加到地图,以及如何在一开始就为地图添加种子。我试过map = nil,但因为它没有结构Elixir不喜欢它。

2 个答案:

答案 0 :(得分:2)

根据您想要的输出,我看到两种可能的解决方案:

  1. 使用值为列表的map
  2. 使用keyword
  3. 在第一种情况下,我会做这样的事情:

    iex> start = 1             
    1
    iex> stop = 3
    3
    iex> Enum.reduce(start..stop, %{}, fn x, acc ->
    ...>   val = Enum.to_list(start..stop)         
    ...>   Map.put(acc, x, val)                    
    ...> end)
    %{1 => [1, 2, 3], 2 => [1, 2, 3], 3 => [1, 2, 3]}
    

    在第二种情况下,这(尽管有点奇怪)可能会做到这一点:

    iex> f = fn(start, stop) -> 
    ...>   (start..stop)
    ...>   |> Enum.map(fn x ->
    ...>     Enum.map(start..stop, fn y -> {String.to_atom("#{x}"), y} end)
    ...>   end)
    ...>   |> Enum.flat_map(&(&1))
    ...> end
    iex>
    iex> f.(1, 3)
    ["1": 1, "1": 2, "1": 3, "2": 1, "2": 2, "2": 3, "3": 1, "3": 2, "3": 3]
    

    编辑:一位工作同事指出了一种更简单的方法来构建上述关键字:

    iex> {start, stop} = {1, 3}
    {1, 3}
    iex> l = for(x <- (start..stop), y <- (start..stop)) do
    ...>   {String.to_atom("#{x}"), y}
    ...> end
    ["1": 1, "1": 2, "1": 3, "2": 1, "2": 2, "2": 3, "3": 1, "3": 2, "3": 3]
    

答案 1 :(得分:0)

你的问题有很多问题。

  1. map = %{ 0, 0}不是正确的地图语法

  2. Elixir的数据是不可变的并且具有范围。 for内的地图不会影响外部地图。

  3. Elixir的地图是哈希地图,只能匹配一个键值。