Ogólna wskazówka: Użyj metody .iterator
, aby uniknąć tworzenia kolekcji pośrednich, a tym samym przyspieszyć obliczenia. (Tylko gdy wymagania eksploatacyjne wymaga. Albo nie.)
scala> def myFun(s: String, i: Int) = s + i
myFun: (s: String, i: Int)java.lang.String
scala> Array("nami", "zoro", "usopp")
res17: Array[java.lang.String] = Array(nami, zoro, usopp)
scala> res17.iterator.zipWithIndex
res19: java.lang.Object with Iterator[(java.lang.String, Int)]{def idx: Int; def idx_=(x$1: Int): Unit} = non-empty iterator
scala> res19 map { case (k, v) => myFun(k, v) }
res22: Iterator[java.lang.String] = non-empty iterator
scala> res22.toArray
res23: Array[java.lang.String] = Array(nami0, zoro1, usopp2)
Należy pamiętać, że iteratory są zmienne, a więc gdy spożywane nie mogą być ponownie użyte.
Na marginesie: Powyższy map
połączenia wymaga zakończenia tupling a następnie funkcja aplikacji. Wymusza to użycie niektórych zmiennych lokalnych. Możesz tego uniknąć używając czarów wyższego rzędu - zamień zwykłą funkcję na akceptującą krotkę, a następnie przekaż ją do map
.
scala> Array("nami", "zoro", "usopp").zipWithIndex.map(Function.tupled(myFun))
res24: Array[java.lang.String] = Array(nami0, zoro1, usopp2)
Lubię czytać swoje odpowiedzi na szybkość rzeczy, ale może być tak przygnębiające czasami ... :-) –
Dzięki. Całkiem miły wybór. – Ivan
Jaka jest szybkość "a.view.zipWithIndex.map {case (s, i) => myFn (s, i)}" w porównaniu do twoich rozwiązań? – gzm0