Create and populate two-dimensional array in Scala - arrays

What's the recommended way of creating a pre-populated two-dimensional array in Scala? I've got the following code:
val map = for {
x <- (1 to size).toList
} yield for {
y <- (1 to size).toList
} yield (x, y)
How do I make an array instead of list? Replacing .toList with .toArray doesn't compile. And is there a more concise or readable way of doing this than the nested for expressions?

On Scala 2.7, use Array.range:
for {
x <- Array.range(1, 3)
} yield for {
y <- Array.range(1, 3)
} yield (x, y)
On Scala 2.8, use Array.tabulate:
Array.tabulate(3,3)((x, y) => (x, y))

Among other ways, you can use use Array.range and map:
scala> Array.range(0,3).map(i => Array.range(0,3).map(j => (i,j)))
res0: Array[Array[(Int, Int)]] = Array(Array((0,0), (0,1), (0,2)), Array((1,0), (1,1), (1,2)), Array((2,0), (2,1), (2,2)))
Or you can use Array.fromFunction:
scala> Array.fromFunction((i,j) => (i,j))(3,3)
res1: Array[Array[(Int, Int)]] = Array(Array((0,0), (0,1), (0,2)), Array((1,0), (1,1), (1,2)), Array((2,0), (2,1), (2,2)))
Scala 2.8 gives you even more options--look through the Array object. (Actually, that's good advice for 2.7, also....)

Related

How do I take slice from an array position to end of the array?

How do I get an array of array with elements like this? Is there an inbuilt scala api that can provide this value (without using combinations)?
e.g
val inp = Array(1,2,3,4)
Output
Vector(
Vector((1,2), (1,3), (1,4)),
Vector((2,3), (2,4)),
Vector((3,4))
)
My answer is below. I feel that there should be an elegant answer than this in scala.
val inp = Array(1,2,3,4)
val mp = (0 until inp.length - 1).map( x => {
(x + 1 until inp.length).map( y => {
(inp(x),inp(y))
})
})
print(mp)
+Edit
Added combination constraint.
Using combinations(2) and groupBy() on the first element (0) of each combination will give you the values and structure you want. Getting the result as a Vector[Vector]] will require some conversion using toVector
scala> inp.combinations(2).toList.groupBy(a => a(0)).values
res11: Iterable[List[Array[Int]]] = MapLike.DefaultValuesIterable
(
List(Array(2, 3), Array(2, 4)),
List(Array(1, 2), Array(1, 3), Array(1, 4)),
List(Array(3, 4))
)
ORIGINAL ANSWER
Note This answer is OK only if the elements in the Seq are unique and sorted (according to <). See edit for the more general case.
With
val v = a.toVector
and by foregoing combinations, I can choose tuples instead and not have to cast at the end
for (i <- v.init) yield { for (j <- v if i < j) yield (i, j) }
or
v.init.map(i => v.filter(i < _).map((i, _)))
Not sure if there's a performance hit for using init on vector
EDIT
For non-unique elements, we can use the indices
val v = a.toVector.zipWithIndex
for ((i, idx) <- v.init) yield { for ((j, jdx) <- v if idx < jdx) yield (i, j) }

Create Array of Arrays with different sizes in scala [duplicate]

How do I create an array of multiple dimensions?
For example, I want an integer or double matrix, something like double[][] in Java.
I know for a fact that arrays changed in Scala 2.8 and that the old arrays are deprecated, but are there multiple ways to do it now and if yes, which is best?
Like so:
scala> Array.ofDim[Double](2, 2, 2)
res2: Array[Array[Array[Double]]] = Array(Array(Array(0.0, 0.0), Array(0.0, 0.0)), Array(Array(0.0, 0.0), Array(0.0, 0.0)))
scala> {val (x, y) = (2, 3); Array.tabulate(x, y)( (x, y) => x + y )}
res3: Array[Array[Int]] = Array(Array(0, 1, 2), Array(1, 2, 3))
It's deprecated. Companion object exports factory methods ofDim:
val cube = Array.ofDim[Float](8, 8, 8)
How to create and use a multi-dimensional array in Scala?
var dd : Array[(Int, (Double, Double))] = Array((1,(0.0,0.0)))

how to read file and split in scala

If I had a file(like csv, txt...).
I wish get two array such as
Array(Array(1.0,2.0),Array(4.0,5.0),Array(7.0, 8.0),Array(10.0,11.0),Array(13.0,14.0))
and
Array(3.0, 6.0, 9.0, 12.0, 15.0)
What's the ideal way to do this in scala?
val rdd = sc.textFile("1.csv").map(_.split(',').map(_.trim().toDouble))
rdd.map(_.take(2)).collect()
res0: Array[Array[Double]] = Array(Array(1.0, 2.0), Array(4.0, 5.0), Array(7.0, 8.0), Array(10.0, 11.0), Array(13.0, 14.0))
rdd.map(_(2)).collect()
res2: Array[Double] = Array(3.0, 6.0, 9.0, 12.0, 15.0)
You can get both arrays in one go, so that you don't need to traverse the data twice:
val (first, second) = {
io.Source.fromFile(name).getLines
.map(_.split(",").map(_.toDouble))
.foldRight(Seq.empty[Array[Double]] -> Seq.empty[Double]) {
case (Array(x, y, z), (as, bs)) => (Array(x, y) +: as, z +: bs)
}
}
Now, you end up with two lists rather that arrays. Of that matters to you, first.toArray and second.toArray will do the conversion for you.
Similar to #Vitaliy Kotlyarenko's answer, but without using 3rd parties like Spark (Spark is great if your data is large, but an overkill otherwise):
val lines: Iterator[String] = scala.io.Source.fromFile("txt.csv").getLines()
val matrix: Array[Array[Double]] = lines.map(_.split(",").map(_.trim.toDouble)).toArray
val twoFirstColumns: Array[Array[Double]] = matrix.map(_.take(2))
val thirdColumn: Array[Double] = matrix.map(_(2))

For comprehension over Option array

I am getting compilation error:
Error:(64, 9) type mismatch;
found : Array[(String, String)]
required: Option[?]
y <- x
^
in a fragment:
val z = Some(Array("a"->"b", "c" -> "d"))
val l = for(
x <- z;
y <- x
) yield y
Why generator over Array does not produce items of the array? And where from requirement to have Option is coming from?
To be more ridiculous, if I replace "yield" with println(y) then it does compile.
Scala version: 2.10.6
This is because of the way for expressions are translated into map, flatmap and foreach expressions. Let's first simplify your example:
val someArray: Some[Array[Int]] = Some(Array(1, 2, 3))
val l = for {
array: Array[Int] <- someArray
number: Int <- array
} yield number
In accordance with the relevant part of the Scala language specification, this first gets translated into
someArray.flatMap {case array => for (number <- array) yield number}
which in turn gets translated into
someArray.flatMap {case array => array.map{case number => number}}
The problem is that someArray.flatMap expects a function from Array[Int] to Option[Array[Int]], whereas we've provided a function from Array[Int] to Array[Int].
The reason the compilation error goes away if yield number is replaced by println(number) is that for loops are translated differently from for comprehensions: it will now be translated as someArray.foreach{case array => array.foreach {case item => println(item)}}, which doesn't have the same typing issues.
A possible solution is to begin by converting the Option to the kind of collection you want to end up with, so that its flatMap method will have the right signature:
val l = for {
array: Array[Int] <- someArray.toArray
number: Int <- array
} yield number
It's the usual "option must be converted to mix monads" thing.
scala> for (x <- Option.option2Iterable(Some(List(1,2,3))); y <- x) yield y
res0: Iterable[Int] = List(1, 2, 3)
Compare
scala> for (x <- Some(List(1,2,3)); y <- x) yield y
<console>:12: error: type mismatch;
found : List[Int]
required: Option[?]
for (x <- Some(List(1,2,3)); y <- x) yield y
^
to
scala> Some(List(1,2,3)) flatMap (is => is map (i => i))
<console>:12: error: type mismatch;
found : List[Int]
required: Option[?]
Some(List(1,2,3)) flatMap (is => is map (i => i))
^
or
scala> for (x <- Some(List(1,2,3)).toSeq; y <- x) yield y
res3: Seq[Int] = List(1, 2, 3)

How to create and use a multi-dimensional array in Scala?

How do I create an array of multiple dimensions?
For example, I want an integer or double matrix, something like double[][] in Java.
I know for a fact that arrays changed in Scala 2.8 and that the old arrays are deprecated, but are there multiple ways to do it now and if yes, which is best?
Like so:
scala> Array.ofDim[Double](2, 2, 2)
res2: Array[Array[Array[Double]]] = Array(Array(Array(0.0, 0.0), Array(0.0, 0.0)), Array(Array(0.0, 0.0), Array(0.0, 0.0)))
scala> {val (x, y) = (2, 3); Array.tabulate(x, y)( (x, y) => x + y )}
res3: Array[Array[Int]] = Array(Array(0, 1, 2), Array(1, 2, 3))
It's deprecated. Companion object exports factory methods ofDim:
val cube = Array.ofDim[Float](8, 8, 8)
How to create and use a multi-dimensional array in Scala?
var dd : Array[(Int, (Double, Double))] = Array((1,(0.0,0.0)))

Resources