Что эквивалентно `mapNotNull`, что приводит к карте? - PullRequest
1 голос
/ 15 мая 2019

Я могу преобразовать List<Int?> в List<Int>, используя функцию mapNotNull, как показано ниже.

    @Test
    fun main() {
        val testData = listOf(1, null, 3, null)
        val noNull = processAwayNull(testData)
    }

    private fun processAwayNull(testData: List<Int?>): List<Int> {
        return testData.mapNotNull{ it }
    }

Как я могу преобразовать Map<String, Int?> в Map<String, Int>? Нижеследующее с testData.filter { it.value != null } не работает, так как все равно выдает Map<String, Int?>.

    @Test
    fun main() {
        val testData = mapOf("One" to 1, "Two" to null, "Three" to 3, "Four" to null)
        val noNull = processAwayNull(testData)
    }

    private fun processAwayNull(testData: Map<String, Int?>): Map<String, Int> {
        return testData.filter { it.value != null }
    }

1 Ответ

4 голосов
/ 15 мая 2019

Ну, не совсем из коробки (в том смысле, что вы получаете Map<String, Int> сразу), но как насчет filterValues?

testData.filterValues { it != null } // gives Map<String, Int?> but without null-values

Комбинируя или заменяя это на mapValues (возможно, вы можете использовать значение по умолчанию вместо null?):

// combining:
testData.filterValues { it != null }
        .mapValues { (_, value) -> value as Int }
// replacing:
testData.mapValues { (_, value) -> value ?: /* default value */ 0 } 

Оба дают Map<String, Int>, но первый создает и заполняет 2 карты под капотом, а второй использует 0 вместо null.

Вы также можете упростить filterValues -вариант с соответствующим неконтролируемым приведением , так как «мы знаем это лучше»:

testData.filterValues { it != null } as Map<String, Int> // unchecked cast, because: we really do know better, do we? ;-)

Кроме того, вы также можете просто обработать все записи, как вы уже знали (используя mapNotNull), а затем создать из него новую карту:

testData.asSequence()
        .mapNotNull { (key, value) ->
            value?.let {
              key to it
            }
        }
        .toMap() // giving Map<String, Int>

Если вам требуется чаще, вы даже можете захотеть использовать собственную функцию расширения:

@Suppress("UNCHECKED_CAST")
fun <K, V> Map<K, V?>.filterValuesNotNull() = filterValues { it != null } as Map<K, V>

Теперь вы можете использовать его следующим образом:

testData.filterValuesNotNull() // giving Map<String, Int>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...