Home > Net >  Scala.js - Convert Uint8Array to Array[Byte]
Scala.js - Convert Uint8Array to Array[Byte]

Time:01-07

How do I implement the following method in Scala.js?

import scala.scalajs.js

def toScalaArray(input: js.typedarray.Uint8Array): Array[Byte] =
  // code in question
  

CodePudding user response:

I'm not intimately familiar with Scala-js, but I can elaborate on some of the questions that came up in the comments, and improve upon your self-answer.

Also I don't quite get why I need toByte calls

class Uint8Array extends Object with TypedArray[Short, Uint8Array] 

Scala treats a Uint8Array as a collection of Short, whereas you are expecting it to be a collection of Byte

Uint8Array's toArray method notes:

This member is added by an implicit conversion from Uint8Array to IterableOps[Short] performed by method iterableOps in scala.scalajs.js.LowestPrioAnyImplicits.

So the method is returning an Array[Short] which you then .map to convert the Shorts to Bytes.

In your answer you posted

 input.toArray.map(_.toByte)

which is technically correct, but it has the downside of allocating an intermediate array of the Shorts. To avoid this allocation, you can perform the .map operation on a .view of the array, then call .toArray on the view.

Views in Scala (and by extension Scala.js) are lightweight objects that reference an original collection plus some kind of transformation/filtering function, which can be iterated like any other collection. You can compose many transformation/filters on a view without having to allocate intermediate collections to represent the results. See the docs page (linked) for more.

input.view.map(_.toByte).toArray

Depending on how you intend to pass the resulting value around, you may not even need to call .toArray. For example if all you need to do is iterate the elements later on, you could just pass the view around as an Iterable[Byte] without ever having to allocate a separate array.

CodePudding user response:

import scala.scalajs.js

def toScalaArray(input: js.typedarray.Uint8Array): Array[Byte] =
  input.toArray.map(_.toByte)
  • Related