views:

240

answers:

2

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?

+2  A: 

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....)

Rex Kerr
+4  A: 

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))
Daniel
Array.tabulate seems sweet, and looks like Array.fromFunction suggested by Rex Kerr in another answer. What's the difference (apart from the fact that I see Array.fromFunction is deprecated in 2.8)? And how do they actually work?
asteinlein
@asteinlein I'm not sure about `fromFunction` -- I had never noticed it before -- but `tabulate` (which is present on `List` on Scala 2.7) works pretty much like the for-comprehension you wrote, but `0 until size` instead of `1 to size`. On Scala 2.7, however, it is one-dimensional only, so you'd need to nest them. On Scala 2.8, you can provide multiple dimensions (up to 5, I think).
Daniel
@Daniel Thanks. For anyone else interested, this works nicely on 2.7:List.tabulate(3, x => List.tabulate(3, y => (x, y)).toArray).toArray
asteinlein