【问题标题】:Transform map into bytes将映射转换为字节
【发布时间】:2019-11-24 08:11:36
【问题描述】:

我有地图:

%{ HEADER: "000000000 000000000000 00000000 ", 
   AM01: %{"C4" => "11111111", "C5" => "1"}, 
   AM04: %{"C2" => "22222222", "C6" => "2"} 
}

我怎样才能把这张地图转换成这样的字节:

"\x02\x1e000000000 000000000000 00000000 \x1e\x1cAM01\x1cC411111111\x1cC51\x1e\x1cAM04\x1cC222222222\x1cC62\x03"

到目前为止,我已经达到了这一点,但最终结果是一个列表。

for segment <- %{AM03: %{"DB" => "1"}, AM04: %{"C2" => "1"}, AM06: %{"CR" => " "}}, into: [] do
  {name, fields} = segment                                                                    
  for field <- fields, into: [] do                                                                      
    {field_name, field_value} = field                                                                          
    "\x1e\x1c#{name}\x1c#{field_name}\x1c#{field_value}"
  end
end

我问:1 - 这是一种功能形式吗? 2 - 我如何在这个的输出上给出一个 Enum.join () ?

【问题讨论】:

  • 到目前为止您尝试过什么?什么不起作用?
  • 事实是我不知道在长生不老药中这样做的正确方法。我来自面向对象编程,我的代码看起来像这样
  • AM01AM04 等值是否应该排序?地图键是未排序的,因此如果是这种情况,您需要在序列化之前对地图进行排序。
  • 在结果上调用Enum.join/1 会出什么问题?请注意"\x1e\x1c" == &lt;&lt;30, 28&gt;&gt; #⇒ true

标签: elixir list-comprehension


【解决方案1】:

Kerenl.SpecialForm.for/1理解支持开箱即用地收集成二进制:

input = %{AM03: %{"DB" => "1"},
          AM04: %{"C2" => "1"},
          AM06: %{"CR" => " "}}

for {name, value} <- input, {fldn, fldv} <- value,
  into: <<>>,
  do: "\x1e\x1c#{name}\x1c" <> fldn <> "\x1c" <> fldv  

#⇒ <<30, 28, 65, 77, 48, 51, ..., 82, 28, 32>>

【讨论】:

    猜你喜欢
    • 2013-05-30
    • 2020-08-19
    • 2017-03-10
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多