Ответ 1
Складки на карте работают так же, как и в списке пар. Вы не можете использовать сокращение, потому что тогда тип результата должен быть таким же, как тип элемента (т.е. Пара), но вам нужна строка. Таким образом, вы используете foldLeft
с пустой строкой в качестве нейтрального элемента. Вы также не можете просто использовать _+_
, потому что тогда вы попытаетесь добавить пару к строке. Вместо этого вы должны использовать функцию, которая добавляет накопленную строку, первое значение пары и второе значение пары. Итак, вы получите следующее:
scala> val m = Map("la" -> "la", "foo" -> "bar")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(la -> la, foo -> bar)
scala> m.foldLeft("")( (acc, kv) => acc + kv._1 + kv._2)
res14: java.lang.String = lalafoobar
Объяснение первого аргумента для сброса:
Как вы знаете, функция (acc, kv) => acc + kv._1 + kv._2
получает два аргумента: вторая - пара ключей-значений, обрабатываемая в данный момент. Первый - это результат, накопленный до сих пор. Однако каково значение acc
, когда обрабатывается первая пара (и пока результат не накапливается)? Когда вы используете reduce
, первое значение acc
будет первой парой в списке (а первое значение kv будет второй парой в списке). Однако это не работает, если вы хотите, чтобы тип результата отличался от типов элементов. Поэтому вместо сокращения мы используем fold, где мы передаем первое значение acc
в качестве первого аргумента foldLeft
.
Вкратце: первый аргумент foldLeft
указывает, что должно быть начальным значением acc
.
Как заметил Том, вы должны иметь в виду, что карты не обязательно поддерживают порядок вставки (Map2 и co. do, но hashmaps нет), поэтому строка может отображать элементы в другом порядке, чем в которые вы вставили.