Давайте разберем вашу проблему более простыми шагами.
- Отфильтровать все пары в
entriesMap
, значение которых не существует в качестве ключа в lookupMap
.
- Сопоставьте оставшиеся пары, чтобы изменить значение для
lookupMap
, связанного с исходным значением.
Таким образом, вы можете написать следующее:
val result =
entriesMap
.filter { case (_, value) => lookupMap.contains(key = value) }
.map { case (key, value) => key -> lookupMap(value) }
Однако каждый раз, когда вы хотите filter
, а затем map
, вы всегда можете использовать collect
(который будет выполнять ту же работу, но только за одну итерацию) .
Таким образом, вы можете написать это:
val result = entriesMap.collect {
case (key, value) if lookupMap.contains(key = value) => key -> lookupMap(value)
}
Теперь, одна "проблема" с приведенным выше кодом заключается в том, что он использует небезопасно apply
над картой , что вызовет исключение, если Их ключ не существует.
Обычно следует использовать метод get
, который будет возвращать значение, заключенное в Option , которое будет None
, если ключ не существовал.
В этом случае доступ небезопасен, потому что мы проверяем, существует ли ключ раньше.
В любом случае, программу можно переосмыслить следующим образом:
- Сопоставьте значения
entriesMap
, пытаясь получить их связанное значение в lookupMap
.
- Отфильтруйте пары, значения которых теперь равны
None
, и разверните Somes
.
Код будет следующим:
val result =
entriesMap
.view // Only if you are in 2.13
.mapValues(value => lookupMap.get(key = value))
.collect { case (key, Some(value)) => key -> value }
.toMap // This is necessary because mapValues returns a view, which is a lazy collection.
// Other option would have been to use just map instead of mapValues.
Наконец, вместо непосредственного использования функций более высокого порядка можно использовать для понимания .
Таким образом, этот код (почти такой же, как код из ответа jwvh) :
val result =
for {
(key, value) <- entriesMap // For each key-value pair in entriesMap...
newValue <- lookupMap.get(key = value) // And for each newValue associated with each original value...
} yield key -> newValue // Yield the key-newValue pair.