В этом контексте вы можете думать о Map
как о списке кортежей. Вы можете создать такой список: List(1 -> 2.0, 3 -> 4.0, 5 -> 6.2)
и вызвать для него foldLeft
(это более или менее точно то, что делает Map.foldLeft
). Если вы понимаете, как foldLeft
работает со списками, то теперь вы знаете, как это работает и с Картами :) Чтобы ответить на ваши конкретные вопросы:
Первый параметр foldLeft
может быть любого типа. Вы также можете передать карту вместо int в своем первом примере. Он не обязательно должен быть того же типа, что и элементы обрабатываемой вами коллекции (хотя и может быть), как в первом примере, и не обязательно должен быть того же типа, что и сама коллекция, как вы есть в последнем примере. Рассмотрим это для примера:
List(1,2,3,4,5,6).foldLeft(Map.empty[String,Int]) { case(map,elem) =>
map + (elem.toString, elem)
}
Это дает тот же результат, что и list.map { x => x.toString -> x }.toMap
. Как видите, первый параметр здесь — Map
, а не List
и не Int
.
Тип, который вы передаете foldLeft
, также является типом, который он возвращает, и типом, который возвращает функция, которую вы передаете. Это не «нулевой элемент». foldLeft
передаст этот параметр вашей функции редуктора вместе с первым элементом списка. Ваша функция объединит два элемента и создаст новое значение того же типа, что и первый параметр. Это значение передается снова, снова со вторым элементом... и т. д. Возможно, будет полезно проверить подпись foldLeft
:
foldLeft[B](z: B)(op: (B, A) ⇒ B): B
Здесь A
— это тип элементов вашей коллекции, а B
может быть любым, единственное требование — чтобы четыре места, где он появляется, имели один и тот же тип.
Вот еще один пример, который (почти) эквивалентен list.mkString(",")
:
List(1,2,3,4,5,6).foldLeft("") {
case("", i) => i.toString
case(s,i) => s + "," + i
}
Как я объяснил в начале, карта в этом контексте — это своего рода список (скорее, последовательность). Точно так же, как «мы всегда брали следующий элемент списка», когда имели дело со списками, в данном случае мы будем брать «следующий элемент карты». Вы сами сказали, что элементы карты — это кортежи, поэтому тип следующего элемента будет таким:
Map("one" -> 1, "two" -> 2, "three" -> 3)
.foldLeft("") {
case("", (key,value)) => key + "->" + value
case(s, (key,value)) => s + ", " + key + "->" + value
}
person
Dima
schedule
06.05.2016