2011-02-03 28 views
10

Teniendo en cuenta:Scala iterador con el mapa y para

val list = List("one","two","three")  
val it = list.toIterator 

puedo correr:

list map ("_" +) -> List(_one, _two, _three) 
for (i <- list) yield("_" + i) -> List(_one, _two, _three) 

Si ejecuta el mismo en el iterador me sale:

it map ("_" +) -> Iterator[java.lang.String] = empty iterator 
for (i <- it) yield("_" + i) -> Iterator[java.lang.String] = empty iterator 

No debería Obtengo otro Iterator [String] (no vacío) después de ejecutar map/for en él?

Respuesta

15
scala> def ints(n: Int): Stream[Int] = n #:: ints(n + 1) 
ints: (n: Int)Stream[Int] 

scala> val list = List("one","two","three") 
list: List[java.lang.String] = List(one, two, three) 

scala> val it = list.toIterator 
it: Iterator[java.lang.String] = non-empty iterator 

scala> it map ("_" +) 
res24: Iterator[java.lang.String] = non-empty iterator 

scala> it map ("_" +) 
res25: Iterator[java.lang.String] = non-empty iterator 

scala> for (i <- it) yield("_" + i) 
res26: Iterator[java.lang.String] = non-empty iterator 

Quizás utilizaste tu iterador?

scala> res26.foreach{println} 
_one 
_two 
_three 

scala> res26 
res28: Iterator[java.lang.String] = empty iterator 

Desde iteradores son con estado y no reajustable, una vez que lo utilizó, está vacío y no puede ser utilizado de nuevo.

su lugar, puede utilizar puntos de vista:

scala> val v = list.view 
v: java.lang.Object with scala.collection.SeqView[java.lang.String,List[java.lang.String]] = SeqView(one, two, three) 

scala> v map ("_" +) 
res29: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...) 

scala> for (i <- v) yield("_" + i) 
res30: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...) 

scala> res29.foreach{println} 
_one 
_two 
_three 

scala> res29 
res32: scala.collection.SeqView[java.lang.String,Seq[_]] = SeqViewM(...) 

scala> res29.foreach{println} 
_one 
_two 
_three 
+1

¡Tienes razón! Debo haber usado el iterador antes de ejecutar los ejemplos. ¡Gracias! :) – ssanj

3

Ver Iterators.

Hay una diferencia importante entre el método foreach en iteradores y el mismo método de colecciones transitables: Cuando se llama a un iterador, foreach dejará el iterador en su extremo cuando se hace. Entonces, llamar de nuevo al next en el mismo iterador generará un NoSuchElementException. Por el contrario, cuando se solicita en una colección, foreach deja la cantidad de elementos en la colección sin cambios (a menos que la función pasada se agregue para eliminar elementos, pero esto se desaconseja, ya que puede conducir a resultados sorprendentes).

...

Como se puede ver, después de la llamada a it.map, el iterador it ha avanzado hasta su final.

Cuestiones relacionadas