转换列表以将前两个字母作为索引进行映射

时间:2019-07-04 19:43:30

标签: elixir

我有清单:

["AM00", "CC11", "CB11"]

我需要像这样在地图中变换此列表:

%{"AM" => "00", "CC" => "11", "CB" => "11"}

我尝试了Enum.map,但是没有用:

["AM00", "CC11", "CB11"]
|> Map.new(&Enum.map(&1, fn x -> x end), %{})

3 个答案:

答案 0 :(得分:3)

二进制模式匹配可以剖析字符串:

   data = ["AM00", "CC11", "CB11"]

   for <<key::binary-size(2), value::binary>> <- data, into: %{} do
     {key, value}
   end

输出:

%{"AM" => "00", "CB" => "11", "CC" => "11"}

仅适用于单字节字符。

要处理UTF-8个字符以及ASCII个字符:

   data = ["èü00", "C€11", "€ä11"]

   for <<char1::utf8, char2::utf8, rest::binary>> <- data, into: %{} do
    {<<char1::utf8, char2::utf8>>, rest}
   end

输出:

%{"C€" => "11", "èü" => "00", "€ä" => "11"}

答案 1 :(得分:3)

我会用Map.new/2String.split_at/2来做到这一点:

Map.new(["AM00", "CC11", "CB11"], &String.split_at(&1, 2))

答案 2 :(得分:2)

  

我需要将此列表转换为[地图] ...我尝试过Enum.map

当您希望结果成为地图时,也可以使用Enum.reduce代替Enum.map。以下示例使用Enum.reduce,并且可以处理单字节ASCII字符以及UTF-8(多字节)字符:

   ["AM00", "CC11", "CB11"]

                initial value for acc variable
                   |
                   V
   |> Enum.reduce(%{},
        fn str, acc -> 
          {first_two, last_two} = String.split_at(str, 2)
          Map.put(acc, first_two, last_two)  # return the new value for acc
        end
      )

输出:

%{"AM" => "00", "CB" => "11", "CC" => "11"}

并且:

    ["èü00", "C€11", "€ä11"]

    |> Enum.reduce(%{},
        fn str, acc -> 
          {first_two, last_two} = String.split_at(str, 2)
          Map.put(acc, first_two, last_two)
        end
       )

输出:

%{"C€" => "11", "èü" => "00", "€ä" => "11"}