foreach
может быть функциональным, но counts += ...
- нет - как побочный эффект, он изменяет структуру данных counts
.
Вот более длинный ответ, который приводит к одной строке, но я пытаюсь объяснить мыслительный процесс:
Когда я пытаюсь найти функциональный способ написания кода, мне часто бывает полезно подумать о том, как, например, я могу использовать ...
- рекурсия
- более продвинутые операции (карта, плоская карта, уменьшение, фильтрация, сгиб, ...)
В этом случае, если вы, например, подумайте, как вы могли бы сделать map
, вы могли бы перефразировать это:
Что я пытаюсь сделать, это если (String, String) финала массива равен кортежу из набора инициализации, добавить его в Map [(String, String), String].
(я предполагаю, что вы случайно поменяли местами финалы / init в своем вопросе, но правильно указали их в бите кода)
как:
Я пытаюсь сопоставить элементы (String, String)
в массиве finals
, и, если один из них находится в init
, вернуть найденный элемент. Возвращенное значение сохраняется в counts
.
Однако в данном случае это не совсем то, что вы хотите - map
требует, чтобы вы возвращали ровно 1 элемент для каждого элемента, который вы отображаете, поэтому вам нужно изменить значение на flatMap
, чтобы избежать этого ограничения. .
val finals: Set[(String, String)] = Set(("m1", "c1"), ("m2", "c1"))
val init: Array[((String, String), String)] = Array((("m1", "c1"), "n"), (("m2", "c2"), "l"), (("m2", "c1"), "k"))
val counts = finals.flatMap( finals_item => init.filter(_._1 == finals_item))
/*
Set[((String, String), String)] = Set(
(("m1", "c1"), "n"),
(("m2", "c1"), "k")
)
*/
Тогда вы просто добавляете .toMap
:
finals.flatMap( finals_item => init.filter(_._1 == finals_item)).toMap