Czy istnieje wbudowana lista/sekwencja, która zachowuje się jak map
i zapewnia również indeks elementu?Jak mogę użyć mapy i otrzymać indeks również w Scali?
Odpowiedz
wierzę szukasz 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
Od: http://www.artima.com/forums/flat.jsp?forum=283&thread=243570
mieć również odmiany, takie jak:
for((e,i) <- List("Mary", "had", "a", "little", "lamb").zipWithIndex) println(i+" "+e)
lub:
List("Mary", "had", "a", "little", "lamb").zipWithIndex.foreach((t) => println(t._2+" "+t._1))
Istnieje CountedIterator
w pliku 2.7.x (który można uzyskać z normalnego iteratora z. Counted). Wydaje mi się, że został wycofany (lub po prostu usunięty) w wersji 2.8, ale łatwo jest przetasować własny. Trzeba, aby móc nazwać iterator:
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)
Albo, zakładając swoją kolekcję ma czas stały dostęp, można odwzorować lista indeksów zamiast rzeczywistej kolekcji:
val ls = List("a","b","c")
0.until(ls.length).map(i => doStuffWithElem(i,ls(i)))
Bardziej eleganckim sposobem na to jest: 'ls.indices.map (i => doStuffWithElem (i, ls (i))' –
@aksiksi No cóż, widząc, że [indeksy] są zaimplementowane jako '0 aż do length'] (https://github.com/scala/scala/blob/2.12.x/src/library/scala/collection/SeqLike.scala#L668) To prawie to samo: P –
hahaha wygrywasz: D –
Proponowane rozwiązania polegają na tym, że tworzą kolekcje pośrednie lub wprowadzają zmienne, które nie są bezwzględnie konieczne. Ostatecznie wszystko, co musisz zrobić, to śledzić liczbę kroków w iteracji. Można to zrobić za pomocą notowania. Otrzymany kod może wyglądać
myIterable map (doIndexed(someFunction))
doIndexed
-Function owija funkcję wewnętrznego, który odbiera zarówno indeksowany z elementów myIterable
. To może być ci znane z JavaScript.
Oto sposób osiągnięcia tego celu. Rozważ następujące narzędzie:
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)
}
}
To wszystko, czego potrzebujesz. Można zastosować to na przykład w następujący sposób:
import TraversableUtil._
List('a','b','c').map(doIndexed((i, char) => char + i))
co powoduje listy
List(97, 99, 101)
W ten sposób można używać zwykłych przesuwny-funkcje kosztem owijając swoją skuteczną funkcję. Narzut jest tworzeniem obiektu do zapamiętania i licznika w nim. W przeciwnym razie to rozwiązanie jest tak samo dobre (lub złe) pod względem pamięci lub wydajności, jak przy użyciu indeksu niepotwierdzonego map
. Cieszyć się!
Użyj. mapa w. zipWithIndex
val myList = List("a", "b", "c")
myList.zipWithIndex.map { case (element, index) =>
println(element, index)
s"${element}(${index})"
}
Wynik:
List("a(0)", "b(1)", "c(2)")
Jest to pierwszy przyzwoity przykład, jaki widziałem, który użył 'mapy' zgodnie z żądaniem zamiast właśnie drukowanie wewnątrz "foreach". –
Czy to skuteczne? – ziggystar
Nie. Wolałbym zrobić: println ("0 Mary \ n1 miał \ n2 a \ n3 mały \ n4 jagnię") –
Cóż, miałem na myśli użycie metody 'zipWithIndex', aby uzyskać indeks wewnątrz pętli/mapy/cokolwiek . – ziggystar