How do I turn an array of bits in an bitstring whe

2019-09-02 18:09发布

问题:

The question is pretty self explanatory. I want to turn something like [true, true, false, true] into the following bitstring 1101.

I assume I need to use Array.pack, but I can't figure out exactly how to do this.

回答1:

It really depends on how exactly you want to represent the boolean Array.

For [true, true, false, true], should it be 0b1101 or 0b11010000? I assume it's the former, and you may get it like this:

data = [true, true, false, true]
out = data
  .each_slice(8) # group the data into segments of 8 bits, i.e., a byte
  .map {|slice|
    slice
      .map{|i| if i then 1 else 0 end } # convert to 1/0
      .join.to_i(2)                     # get the byte representation
  }
  .pack('C*')
p out #=> "\r"

PS. There may be further endian problem depending on your requirements.



回答2:

You can use map and join:

ary = [true, true, false, true]

ary.map { |b| b ? 1.chr : 0.chr }.join
#=> "\x01\x01\x00\x01"


回答3:

You can indeed do this with pack

First turn your booleans into a string

bit_string = [true, false, false,true].map {|set| set ? 1 :0}.join

Pad the string with zeroes if needed

bit_string = "0" * (8 - (bit_string.length % 8)) + bit_string if bit_string.length % 8 != 0

Then pack

[bit_string].pack("B*")


回答4:

You can define a to_i method for TrueClass and FalseClass. Something like this:

class TrueClass
  def to_i
    1
  end
end
class FalseClass
  def to_i
    0
  end
end
[true, true, false, true].map(&:to_i).join
# => "1101"