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.
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.
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.
You can use map
and join
:
ary = [true, true, false, true]
ary.map { |b| b ? 1.chr : 0.chr }.join
#=> "\x01\x01\x00\x01"
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*")
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"