2011-08-25 11 views
8

Si tiene una estructura de datos mutable como Array, ¿es posible utilizar operaciones map o algo similar para cambiar sus valores?¿Mutar una colección mutable utilizando el mapa?

Di que tengo val a = Array(5, 1, 3), ¿cuál es la mejor manera de decir, restando 1 de cada valor? El mejor que he llegado con es

for(i <- 0 until a.size) { a(i) = a(i) - 1 } 

supongo forma sería hacer que la matriz de un var más bien una que val así que puedo decir

a = a map (_-1) 

edición: bastante fácil de rodar mi propia si no hay nada incorporada, aunque no sé cómo generalizar a otras colecciones mutables

scala> implicit def ArrayToMutator[T](a: Array[T]) = new { 
    | def mutate(f: T => T) = a.indices.foreach {i => a(i) = f(a(i))} 
    | } 
ArrayToMutator: [T](a: Array[T])java.lang.Object{def mutate(f: (T) => T): Unit} 

scala> val a = Array(5, 1, 3) 
a: Array[Int] = Array(5, 1, 3) 

scala> a mutate (_-1) 

scala> a 
res16: Array[Int] = Array(4, 0, 2) 

Respuesta

17

Si no se preocupan por los índices, que desea el método transform.

scala> val a = Array(1,2,3) 
a: Array[Int] = Array(1, 2, 3) 

scala> a.transform(_+1) 
res1: scala.collection.mutable.WrappedArray[Int] = WrappedArray(2, 3, 4) 

scala> a 
res2: Array[Int] = Array(2, 3, 4) 

(devuelve una copia de la matriz envuelta de manera que el encadenamiento de las transformaciones es más eficiente, pero la matriz original se modifica como se puede ver.)

+0

fresca, Pensé que debía haber algo. ¿Alguna idea sobre eficiencia comparativa entre esto, proxenetismo de la biblioteca como en la pregunta, o usando una función normal? –

+1

@Luigi Plinge: si especializas tu versión y estás utilizando tipos primitivos, la tuya será más rápida (a menos que aciertes un error de especialización, del que hay algunos). De lo contrario, la biblioteca es tan rápida como usted. –

4

Cómo sobre el uso foreach ya que don' t realmente desea devolver una colección modificada, desea realizar una tarea para cada elemento. Por ejemplo:

a.indices.foreach{i => a(i) = a(i) - 1} 

o

a.zipWithIndex.foreach{case (x,i) => a(i) = x - 1} 
+0

'indices' parece como un método útil –

Cuestiones relacionadas