How to convert Array<T> to TArray?


#1

I'm currently creating a waveform generator which reads .wav audio files. I would ideally like to have my program look as follows:

public data class Wave(path : Path) {   val audioSamples: ByteArray   val header : WaveHeader   val frames : Frames

  {
  if (!hasWavExtension(path))
           throw WaveException(“Does not have the .wav file extension”)

  &nbsp;&nbsp;val rawData = readRawData(path)

  &nbsp;&nbsp;audioSamples = rawData.drop(WaveHeader.HeaderByteLength)
  &nbsp;&nbsp;header = parseWaveHeader(rawData.take(WaveHeader.HeaderByteLength))
  &nbsp;&nbsp;frames = readFrames(audioSamples, header)

  }


Putting aside the limitation of the current implementation (a wave header isn’t strictly an X amount of bytes), the compiler complains because the .drop and take functions convert my ByteArray to Array<Byte>. Converting it back is possible, but a pain.

Attempts to elegantly convert the Array<Byte> back:

audioSamples = rawData.drop(WaveHeader.HeaderByteLength) as ByteArray // Exception, cannot convert

audioSamples = rawData.drop(WaveHeader.HeaderByteLength).copyToArray() as ByteArray // As above

audioSamples = byteArray(*rawData.drop(WaveHeader.HeaderByteLength).copyToArray()) // Syntax error, but this works for Array<String> ???

val samples = rawData.drop(WaveHeader.HeaderByteLength).copyToArray() audioSamples = byteArray(*samples) // As above

Instead, I have to forego immutability and loop for the desired amount of bytes:

val samples = rawData.drop(WaveHeader.HeaderByteLength).copyToArray() audioSamples = ByteArray(WaveHeader.HeaderByteLength) for (sample in samples.withIndices())   audioSamples[sample.first] = sample.second

I would like to ask if there is any other way that I'm missing because of my inexperience? Could I create the behavior I want with an extension function? If so, how? Retrospectively, am I not even supposed to use TArrays when writing Kotlin? Is Kotlin designed with Array<T> in mind?


#2

If I'm not mistaken, there is no such function in the standard library yet, but you can write one yourself:

fun Collection<Byte>.toByteArray(): ByteArray {   val result = ByteArray(size())   for ((i, v) in withIndices()) {   result[i] = v   }   return result }

Now you can write

audioSamples = rawData.drop(WaveHeader.HeaderByteLength).toByteArray()

#3

We already have an issue about that: http://youtrack.jetbrains.com/issue/KT-4180.