Как преобразовать Seq[Byte] в Array[Boolean], представляющий каждый бит в Scala

Есть ли лучший способ преобразовать последовательность байтов в 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 лучше?


person Kevin Herron    schedule 28.04.2013    source источник


Ответы (2)


Во-первых, аккумулятор в 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
person 4e6    schedule 28.04.2013
comment
Я сделал его изменяемым, чтобы сократить накладные расходы на создание новой коллекции на каждом этапе... что касается вашего второго пункта: DOH! Да, это кажется очевидным подходом, не так ли. Я новичок в Scala и функциональном программировании в целом. Я часто ловлю себя на том, что пытаюсь стать слишком хитрым для своего же блага. - person Kevin Herron; 29.04.2013
comment
Есть отличная книга о FP в scala. Вы обязательно должны это проверить. - person 4e6; 29.04.2013

Что бы это ни стоило, вы можете преобразовать байт в BinaryString, а затем в последовательность логических значений с помощью:

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

Результат: Vector(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
person Keith Pinson    schedule 29.04.2013