Elixir:将位列表转换为二进制

时间:2018-05-16 07:49:37

标签: elixir

我有一个表示位的整数列表;例如[1,0,0,1,1,0,0,1,0,0,0,1,1,1,0,0]我希望将其转换为二进制文件<<153, 28>>,我知道列表的长度始终是8的倍数。

我查看过Elixir文档,但是我找不到任何帮助(我已经找到了确切的函数,但是还有一个函数可以将一些函数附加到二进制文件中)。

我已经编写了一个解决问题的函数(下面),但我希望有更好的方法,因为我认为我的函数看起来太复杂了。

def list_to_binary(l) do 
  if length(l) >= 8 do
    << Enum.at(l, 0) :: size(1),
      Enum.at(l, 1) :: size(1),
      Enum.at(l, 2) :: size(1),
      Enum.at(l, 3) :: size(1),
      Enum.at(l, 4) :: size(1),
      Enum.at(l, 5) :: size(1),
      Enum.at(l, 6) :: size(1),
      Enum.at(l, 7) :: size(1)
    >> <> list_to_binary(Enum.drop l, 8)
  else
    if length(l) == 0 do
      <<>>
    else
      l = l ++ List.duplicate(0, 8 - length(l))
      list_to_binary(l)
    end
  end
end

2 个答案:

答案 0 :(得分:2)

使用Kernel.SpecialForms.for/1理解:into keyword argument接受任何实施Collectable协议的内容,binary确实实现了该协议。

for i <- [1,0,0,1,1,0,0,1,0,0,0,1,1,1,0,0], do: <<i::1>>, into: <<>>
#⇒ <<153, 28>>

答案 1 :(得分:1)

与@ mudasobwa上面的答案类似,你可以做到

Enum.into([1,0,0,1,1,0,0,1,0,0,0,1,1,1,0,0], <<>>, fn bit -> <<bit :: 1>> end)

我认为这可以稍微清理一下,因为Enum.into可以很容易地放入管道。