Есть ли какой-либо встроенный список / последовательность, который ведет себя как map
и также предоставляет индекс элемента?
Ответы:
Я полагаю, вы ищете 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
От: http://www.artima.com/forums/flat.jsp?forum=283&thread=243570
У вас также есть такие варианты, как:
for((e,i) <- List("Mary", "had", "a", "little", "lamb").zipWithIndex) println(i+" "+e)
или:
List("Mary", "had", "a", "little", "lamb").zipWithIndex.foreach( (t) => println(t._2+" "+t._1) )
while
циклом, который, вероятно, является одним из самых быстрых вариантов.
view
you должно иметь возможность предотвратить создание и перемещение дополнительного списка.
Используйте. карта в формате . zipWithIndex
val myList = List("a", "b", "c")
myList.zipWithIndex.map { case (element, index) =>
println(element, index)
s"${element}(${index})"
}
Результат:
List("a(0)", "b(1)", "c(2)")
map
как запрошенный, а не просто печатался внутри foreach
.
Предлагаемые решения страдают тем фактом, что они создают промежуточные коллекции или вводят переменные, которые не являются строго необходимыми. В конечном итоге все, что вам нужно сделать, это отслеживать количество шагов итерации. Это можно сделать с помощью мемоизации. Результирующий код может выглядеть как
myIterable map (doIndexed(someFunction))
В doIndexed
-Функция обертывания функции интерьера , который принимает как индекс в элементыmyIterable
. Это может быть вам знакомо по JavaScript.
Вот способ достичь этой цели. Рассмотрим следующую утилиту:
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)
}
}
Это уже все, что вам нужно. Вы можете применить это, например, следующим образом:
import TraversableUtil._
List('a','b','c').map(doIndexed((i, char) => char + i))
что приводит к списку
List(97, 99, 101)
Таким образом, вы можете использовать обычные Traversable-функции за счет обертывания вашей эффективной функции. Накладные расходы - это создание мемоизирующего объекта и счетчика в нем. В противном случае это решение будет таким же хорошим (или плохим) с точки зрения памяти или производительности, как и неиндексированный map
. Наслаждайтесь!
coll.view.zipWithIndex
вместоcoll.zipWithIndex
Есть CountedIterator
в 2.7.x (который вы можете получить из обычного итератора с .counted). Я считаю, что он устарел (или просто удален) в версии 2.8, но его достаточно легко свернуть самостоятельно. Вам нужно иметь возможность назвать итератор:
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)
Или, если ваша коллекция имеет постоянное время доступа, вы можете сопоставить список индексов вместо фактической коллекции:
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
это реализовано, поскольку0 until length
это почти то же самое: P
List
был действительно плохим. Однако я упомянул, что это подходит, если ваша коллекция имеет постоянное время доступа. Надо было выбрать Array
.
Используйте .map в .zipWithIndex со структурой данных карты
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"
}
Полученные результаты
List(
Key: a - Value: hello with Index: 0,
Key: b - Value: world with Index: 1,
Key: c - Value: again with Index: 2
)
Это можно сделать двумя способами.
ZipWithIndex: автоматически создает счетчик, начиная с 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")
}
Вывод обоих кодов будет:
0 is Sun
1 is Mon
2 is Tue
3 is Wed
4 is Thu
5 is Fri
6 is Sat
Zip : используйте метод zip с Stream, чтобы создать счетчик. Это дает вам возможность контролировать начальное значение.
for ((day, count) <- days.zip(Stream from 1)) {
println(s"$count is $day")
}
Результат:
1 is Sun
2 is Mon
3 is Tue
4 is Wed
5 is Thu
6 is Fri
7 is Sat
zipWithIndex
метод для получения индекса внутри цикла / карты / чего угодно.