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
toIterableOps[Short]
performed by methoditerableOps
inscala.scalajs.js.LowestPrioAnyImplicits
.
So the method is returning an Array[Short]
which you then .map
to convert the Short
s to Byte
s.
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)