从凤凰视图渲染位串

Rendering bitstring from phoenix view

我有一个 bitstring = <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>> 形式的位串。我想渲染,但 poison 或 Jason 似乎没有渲染。在这样的响应中呈现位串的最佳方式是什么。

像这样

bits = <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>>
render(conn, "bits.json", bits: bits)

无法将 46 位转换为字节数组。 AFAICT,这里有两个最自然的选择。

人们可能会使用具有值的二进制表示的数组:

for << <<c::1>> <- <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>> >>, do: c    
#⇒ [0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
#   0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]

或者一个人可能会使用上面加入的二进制文件:

(for << <<c::1>> <- <<18::6,8::4,2::5,16::5,18::6,3000::16,0::4>> >>, do: c)
|> Enum.join()
#⇒ "0100101000000101000001001000001011101110000000"

如果目标是编码然后解码位串,并且存储效率是一个问题,我会使用 term_to_binary 将位串转换为二进制,然后将其编码为基础-64 字符串。这将为您提供一个很好的紧凑型位串表示,稍后可以对其进行解码。

defmodule A do
  def encode(bitstring) when is_bitstring(bitstring) do
    bitstring |> :erlang.term_to_binary() |> Base.encode64
  end

  def decode(binary) do
    decoded = binary |> Base.decode64!() |> :erlang.binary_to_term([:safe])
    if is_bitstring(decoded), do: decoded, else: nil
  end
end

IO.inspect encoded = A.encode(<<0::220>>)
IO.inspect A.decode(encoded)

输出:

"g00AAAAcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0::size(4)>>

您可以将 A.encode 的输出传递给您的 JSON 编码器,并在使用 JSON 解码器解码后调用 A.decode