How do I turn an array of bits in an bitstring where each bit represents one boolean in Ruby

二次信任 提交于 2019-12-11 20:34:53

问题


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"


来源:https://stackoverflow.com/questions/29554317/how-do-i-turn-an-array-of-bits-in-an-bitstring-where-each-bit-represents-one-boo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!