2012-10-12 22 views
13

Voglio lavorare con un array multidimensionale indicizzato immutabile. La struttura che ha senso è un Vector di Vector s.Come si creano vettori multidimensionali in Scala?

scala> val v = Vector[Vector[Int]](Vector[Int](1,2,3), Vector[Int](4,5,6), Vector[Int](7,8,9)) 
v: scala.collection.immutable.Vector[Vector[Int]] = Vector(Vector(1, 2, 3), Vector(4, 5, 6), Vector(7, 8, 9)) 

Sarebbe bello creare una matrice vuota semplicemente specificando le dimensioni, come si può con Array.ofDim.

scala> a = Array.ofDim[Int](3,3) 
a: Array[Array[Int]] = Array(Array(0, 0, 0), Array(0, 0, 0), Array(0, 0, 0)) 

Tuttavia, non v'è alcuna Vector.ofDim, la funzione, e non riesco a trovare un equivalente.

Esiste un equivalente di Array.ofDim per oggetti immutabili? Se no, perché no?

+0

È per un programma che risolve i puzzle di Sudoku. Una soluzione parziale è rappresentata come un array nxn di 'Option [Int]'. Data una soluzione parziale _p_, il programma può ipotizzare un altro _p'_ inserendo numeri interi nell'array. Poiché ogni _p_ può generare più _p'_ s, voglio che ogni soluzione parziale sia immutabile. Le mie opzioni sembrano essere 1) rappresentare i numeri con una 'matrice 'privata 2) rappresentano i numeri con un' Vector'. (2) sembra più nello stile funzionale, ma creare 'Vector's di' Vector's è scomodo. –

+0

È possibile rappresentare matrici/elenchi multidimensionali utilizzando singole dimensioni. – pedrofurla

+1

Preparati a divertirti cercando di aggiornare le celle in un vettore multidimensionale. Probabilmente è più semplice avere un metodo di utilità: 'def update [T] (v: Vector [Vector [T]]) (c1: Int, c2: Int) (newVal: T) = v.updated (c1, v (c1) .updated (c2, newVal)) '. Oppure se hai bisogno di dimensioni superiori, copia e incolla da http://stackoverflow.com/a/12612908/770361. –

risposta

18

Ogni classe di raccolta standard ha un oggetto associato con i metodi di fabbrica, tra cui fill. Per esempio:

Vector.fill(3, 3)(0) 

Vedere the relevant scaladoc.

+0

Link dà 404. Il link corrente è (25-25-2016): http://www.scala-lang.org/api/current/scala/collection/immutable/Vector.html – eddy147

+0

Ho aggiornato il collegamento (era appena analizzato da SO). Si scopre che lo scaladoc corrente continua a non menzionare 'fill' quindi mi sono attenuto a scala 2.9.1. –

+0

Non sei sicuro del motivo per cui non riesci a vederlo, ma 'fill' è lì, ed è stato per molto tempo: http://www.scala-lang.org/api/current/scala/collection/immutable/Vector$ .html # fill [A] (n1: Int, n2: Int) (elem: => A): CC [CC [A]] È nell'oggetto complementare, ovviamente –

5

È possibile utilizzare fill:

scala> Vector.fill(3)(Vector.fill(3)(0)) 
res1: scala.collection.immutable.Vector[scala.collection.immutable.Vector[Int]] = 
     Vector(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)) 
13

C'è un metodo di creazione chiamato tabulate che consente di impostare i contenuti in base all'indice:

scala> Vector.tabulate(3,3){ (i,j) => 3*i+j+1 } 
res0: scala.collection.immutable.Vector[scala.collection.immutable.Vector[Int]] = 
Vector(Vector(1, 2, 3), Vector(4, 5, 6), Vector(7, 8, 9)) 

Se avete solo bisogno zeri (o qualche altra costante), è possibile utilizzare fill invece:

scala> Vector.fill(3,3)(0) 
res1: scala.collection.immutable.Vector[scala.collection.immutable.Vector[Int]] = 
Vector(Vector(0, 0, 0), Vector(0, 0, 0), Vector(0, 0, 0)) 
Problemi correlati