views:

105

answers:

3

Hi,

I´m pretty new to scala, so excuse my question if it is dumb.

Is there any way to build dynamic multi-dimensional arrays in scala. I know arrays in scala must be initializes in its sizes and dimensions, so I don't want that. The Datastructure should be dynamic. I tried to build it with lists in lists, but I lost myself some way :)

There are so many different types, maybe I just didn't find the right one. So please push me to the right direction.

+4  A: 

Well, it depends a lot on what you intend to do with it, but your best guess is IndexedSeq[IndexedSeq[T]] (or deeper nestings), using Vector as the implementation for IndexedSeq (it's the default implementation anyway).

For example:

scala> IndexedSeq(IndexedSeq(1, 2, 3), IndexedSeq(4, 5), IndexedSeq(6, 7, 8, 9)) res0: IndexedSeq[IndexedSeq[Int]] = Vector(Vector(1, 2, 3), Vector(4, 5), Vector(6, 7, 8, 9))

Daniel
Hi, thy for your answer.How do I gain access to a single value in this IndexSequence, e.g. second "row", second "column", res0(2)(2) or something like that?
evildead
@evildead: Yes. But as I'm sure you know, Scala has a REPL, so things like that are at least as easy to confirm yourself empirically as they are to get confirmed here. Oh, except that the second row and second column would be `vectorOfVectors(1)(1)`.
Randall Schulz
Yeah I, I just wanna avoid any mistake :)And of course it's (1)(1), was late last night. Thank you.
evildead
@evildead I just noticed you want mutable data structures. For some reason, I thought you wanted a good _immutable_ data structure. `Vector` is good because it is persistent and with log(N) copy/resize, but if you want mutability, I think Rex Kerr has the best one so far.
Daniel
ok, I see my main problem was I used my distribution packets for scala, which was 2.7.7. So most of the constructs I found didnt work. Updating to 2.8 makes many things clear :)
evildead
+3  A: 

You may create an array of 2 dims dynamically like this:

val aa : Array[Array[Int]] = Array.ofDim (3, 4)

Well, yes, I see, the size is fixed. How about that:

val i = random.nextInt (5) + 1
val j = new GregorianCalendar (). get (Calendar.DAY_OF_WEEK)
val aa : Array[Array[Int]] = Array.ofDim (i, j)

Yes, it is bound to two dimensions. How would you use an array of previously unknown dimension?

Well - at least, you can:

val aa : Array [Int] = Array.ofDim (2)

aa: Array[Int] = Array(0, 0)

val aaa = Array.fill (3) (aa)         

aaa: Array[Array[Int]] = Array(Array(0, 0), Array(0, 0), Array(0, 0))

user unknown
+4  A: 

If you want to do something like

a(5) = // result of some computation

then you'll need to use something from the mutable collections hierarchy. I'd suggest ArrayBuffer.

scala> import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ArrayBuffer

scala> val a = ArrayBuffer.fill(3,3)(0)
a: scala.collection.mutable.ArrayBuffer[scala.collection.mutable.ArrayBuffer[Int]] = ArrayBuffer(ArrayBuffer(0, 0, 0), ArrayBuffer(0, 0, 0), ArrayBuffer(0, 0, 0))

scala> a(2)(1) = 4

scala> a(0) = ArrayBuffer(1,2,3)

scala> a
res2: scala.collection.mutable.ArrayBuffer[scala.collection.mutable.ArrayBuffer[Int]] = ArrayBuffer(ArrayBuffer(1, 2, 3), ArrayBuffer(0, 0, 0), ArrayBuffer(0, 4, 0))

Note that fill lets you automatically create and initialize up to 5D structures. Note also that you can extend the length of these, but it won't extend the entire multidimensional structure, just the one you add to. So, for example,

scala> a(2) += 7 // Add one element to the end of the array
res3: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(0, 4, 0, 7)

scala> a
res4: scala.collection.mutable.ArrayBuffer[scala.collection.mutable.ArrayBuffer[Int]]
= ArrayBuffer(ArrayBuffer(1, 2, 3), ArrayBuffer(0, 0, 0), ArrayBuffer(0, 4, 0, 7))
Rex Kerr
thank you very much.
evildead
I comment it here again, as I see now my problem was using 2.7.7 from my distribution. I was wondering why all the things I found out there doesnt work for me. Now with 2.8 all works fine. I tested your answer and evrything works out fine. Its exactly what I needed. Big thanks again
evildead