Réponses:
Je crois que vous recherchez zipWithIndex?
scala> val ls = List("Mary", "had", "a", "little", "lamb")
scala> ls.zipWithIndex.foreach{ case (e, i) => println(i+" "+e) }
0 Mary
1 had
2 a
3 little
4 lamb
De: http://www.artima.com/forums/flat.jsp?forum=283&thread=243570
Vous avez également des variantes comme:
for((e,i) <- List("Mary", "had", "a", "little", "lamb").zipWithIndex) println(i+" "+e)
ou:
List("Mary", "had", "a", "little", "lamb").zipWithIndex.foreach( (t) => println(t._2+" "+t._1) )
while
boucle, qui est probablement parmi les options les plus rapides.
view
vous devrait être en mesure d'empêcher la création et la traversée d'une liste supplémentaire.
Utilisation . carte en. zipWithIndex
val myList = List("a", "b", "c")
myList.zipWithIndex.map { case (element, index) =>
println(element, index)
s"${element}(${index})"
}
Résultat:
List("a(0)", "b(1)", "c(2)")
map
comme demandé au lieu de simplement imprimer dans un fichier foreach
.
Les solutions proposées souffrent du fait qu'elles créent des collections intermédiaires ou introduisent des variables qui ne sont pas strictement nécessaires. En fin de compte, tout ce que vous avez à faire est de suivre le nombre d'étapes d'une itération. Cela peut être fait en utilisant la mémorisation. Le code résultant pourrait ressembler à
myIterable map (doIndexed(someFunction))
La fonction doIndexed
-Function enveloppe la fonction intérieure qui reçoit à la fois un index et les éléments de myIterable
. Cela peut vous être familier à partir de JavaScript.
Voici un moyen d'atteindre cet objectif. Considérez l'utilitaire suivant:
object TraversableUtil {
class IndexMemoizingFunction[A, B](f: (Int, A) => B) extends Function1[A, B] {
private var index = 0
override def apply(a: A): B = {
val ret = f(index, a)
index += 1
ret
}
}
def doIndexed[A, B](f: (Int, A) => B): A => B = {
new IndexMemoizingFunction(f)
}
}
C'est déjà tout ce dont vous avez besoin. Vous pouvez appliquer ceci par exemple comme suit:
import TraversableUtil._
List('a','b','c').map(doIndexed((i, char) => char + i))
qui aboutit à la liste
List(97, 99, 101)
De cette façon, vous pouvez utiliser les fonctions Traversable habituelles au détriment de l'emballage de votre fonction effective. La surcharge est la création de l'objet de mémorisation et du compteur qui s'y trouve. Sinon, cette solution est aussi bonne (ou mauvaise) en termes de mémoire ou de performances que l'utilisation de non indexé map
. Prendre plaisir!
coll.view.zipWithIndex
place decoll.zipWithIndex
Il existe CountedIterator
en 2.7.x (que vous pouvez obtenir à partir d'un itérateur normal avec .counted). Je pense qu'il est obsolète (ou simplement supprimé) dans la version 2.8, mais il est assez facile de lancer le vôtre. Vous devez être en mesure de nommer l'itérateur:
val ci = List("These","are","words").elements.counted
scala> ci map (i => i+"=#"+ci.count) toList
res0: List[java.lang.String] = List(These=#0,are=#1,words=#2)
Ou, en supposant que votre collection a un temps d'accès constant, vous pouvez mapper la liste des index au lieu de la collection réelle:
val ls = List("a","b","c")
0.until(ls.length).map( i => doStuffWithElem(i,ls(i)) )
ls.indices.map(i => doStuffWithElem(i, ls(i))
indices
est implémenté,0 until length
c'est à peu près la même chose: P
List
était vraiment médiocre. J'ai cependant mentionné que cela convient si votre collection a un temps d'accès constant. J'aurais dû choisir Array
.
Utilisez .map dans .zipWithIndex avec la structure de données Map
val sampleMap = Map("a" -> "hello", "b" -> "world", "c" -> "again")
val result = sampleMap.zipWithIndex.map { case ((key, value), index) =>
s"Key: $key - Value: $value with Index: $index"
}
Résultats
List(
Key: a - Value: hello with Index: 0,
Key: b - Value: world with Index: 1,
Key: c - Value: again with Index: 2
)
Il y a deux façons de le faire.
ZipWithIndex: crée un compteur commençant automatiquement par 0.
// zipWithIndex with a map.
val days = List("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
days.zipWithIndex.map {
case (day, count) => println(s"$count is $day")
}
// Or use it simply with a for.
for ((day, count) <- days.zipWithIndex) {
println(s"$count is $day")
}
La sortie des deux codes sera:
0 is Sun
1 is Mon
2 is Tue
3 is Wed
4 is Thu
5 is Fri
6 is Sat
Zip : utilisez la méthode zip avec un Stream pour créer un compteur. Cela vous donne un moyen de contrôler la valeur de départ.
for ((day, count) <- days.zip(Stream from 1)) {
println(s"$count is $day")
}
Résultat:
1 is Sun
2 is Mon
3 is Tue
4 is Wed
5 is Thu
6 is Fri
7 is Sat
Si vous avez également besoin de rechercher les valeurs de la carte (comme je devais le faire):
val ls = List("a","b","c")
val ls_index_map = ls.zipWithIndex.toMap
zipWithIndex
méthode pour obtenir l'index dans une boucle / map / peu importe.