如何在Scala中将Seq[Byte]转换为表示每个位的Array[Boolean]

3

有没有更好的方法将一系列字节转换为一个Seq[Boolean],其中每个元素代表来自字节序列的一个位?

我目前正在使用byte2Bools,但它似乎有点过于繁重...

object Main extends App {

  private def byte2Bools(b: Byte) =
    (0 to 7).foldLeft(ArrayBuffer[Boolean]())((bs, i) => bs += isBitSet(b, i))

  private def isBitSet(byte: Byte, bit: Int) =
    ((byte >> bit) & 1) == 1

  val bytes = List[Byte](1, 2, 3)
  val bools = bytes.flatMap(b => byte2Bools(b))

  println(bools)

}

也许真正的问题是:byte2Bools的更好实现方式是什么?
2个回答

4
首先,在 foldLeft 中的累加器不一定需要是可变集合。
def byte2Bools(b: Byte): Seq[Boolean] = 
  (0 to 7).foldLeft(Vector[Boolean]()) { (bs, i) => bs :+ isBitSet(b)(i) }

第二,您可以使用isBitSet将初始序列直接映射。
def byte2Bools(b: Byte): Seq[Boolean] =
  0 to 7 map isBitSet(b)

def isBitSet(byte: Byte)(bit: Int): Boolean =
  ((byte >> bit) & 1) == 1

我将其设置为可变的,以减少每一步创建新集合的开销...至于您提出的第二点:天啊!是的,那似乎是显而易见的方法。我是Scala和函数式编程的新手。我经常发现自己试图过于聪明,结果不好。 - Kevin Herron
有一本关于Scala中的FP非常好的书,你绝对应该去看看。 - 4e6

1

无论价值如何,您都可以通过以下方式将Byte转换为BinaryString,然后再转换为一系列布尔值:

  val b1 : Byte = 7
  (0x100 + b1).toBinaryString.tail.map{ case '1' => true; case _ => false }

结果为:向量(false,false,false,false,false,true,true,true)


而且,你可以通过以下方式将布尔值转换为字节:

  val s1 = Vector(false, false, false, false, false, true, true, true)
  Integer.parseInt( s1.map{ case true => '1'; case false => '0' }.mkString, 2 ).toByte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接