What is the correct way to get a subarray in Scala?
I am trying to get a subarray in scala, and I am a little confused on what the proper way of doing it is. What I would like the most would be something like how you can do it in python:
x = [3, 2, 1]
x[0:2]
but I am fairly certain you cannot do this.
The most obvious way to do it would be to use the Java Arrays util library.
import java.util.Arrays
val start = Array(1, 2, 3)
Arrays.copyOfRange(start, 0, 2)
But it always makes me feel a little dirty to use Java libraries in Scala. The most "scalaic" way I found to do it would be
def main(args: List[String]) {
val start = Array(1, 2, 3)
arrayCopy(start, 0, 2)
}
def arrayCopy[A](arr: Array[A], start: Int, end: Int)(implicit manifest: Manifest[A]): Array[A] = {
val ret = new Array(end - start)
Array.copy(arr, start, ret, 0, end - start)
ret
}
but is there a better way?
Solution 1:
You can call the slice method:
scala> Array("foo", "hoo", "goo", "ioo", "joo").slice(1, 4)
res6: Array[java.lang.String] = Array(hoo, goo, ioo)
It works like in python.
Solution 2:
Imagine you have an array with elements from a
to f
scala> val array = ('a' to 'f').toArray // Array('a','b','c','d','e','f')
Then you can extract a sub-array from it in different ways:
-
Dropping the first n first elements with
drop(n: Int)
array.drop(2) // Array('c','d','e','f')
-
Take the first n elements with
take(n: Int)
array.take(4) // Array('a','b','c','d')
-
Select any interval of elements with
slice(from: Int, until: Int)
. Note thatuntil
is excluded.array.slice(2,4) // Array('c','d')
The slice method is stricly equivalent to:
array.take(4).drop(2) // Array('c','d')
-
Exclude the last n elements with
dropRight(n: Int)
:array.dropRight(4) // Array('a','b')
-
Select the last n elements with
takeRight(n: Int)
:array.takeRight(4) // Array('c','d','e','f')
Reference: Official documentation
Solution 3:
An example of extracting specific columns from a 2D Scala Array (original_array):
import scala.collection.mutable.ArrayBuffer
val sub_array = ArrayBuffer[Array[String]]()
val columns_subset: Seq[String] = Seq("ColumnA", "ColumnB", "ColumnC")
val columns_original = original_array(0)
for (column_now <- columns_subset) {
sub_array += original_array.map{_(columns_original.indexOf(column_now))}
}
sub_array