Есть ли способ отфильтровать null Any? ценностей на карте Котлина?

Я пытаюсь думать о функции, которая позволила бы рассматривать объект Map<String, Any?> метод Map<String,Any> через тип путем применения одной функции.

Я довольно новичок в функциях преобразования в Котлине и пробовал filter и filterValues filterNot на карте:

 val input = mapOf(Pair("first",null)) val filtered: Map<String,Any> = input.filter { it.value!=null } 

он также не компилируется ни с одним из этих

 input.filterValues { it!=null } input.filterNot { it.value==null } input.filterNot { it.value is Nothing } 

Самое близкое, что я могу получить, это применять несколько шагов или иметь предупреждение о немедленном росте. Я бы подумал, что фильтрация значений, равных !=null будет достаточной. Моя единственная мысль состоит в том, что это связано с дженериками?

Функции фильтра возвращают карту с теми же родовыми типами, что и исходная карта. Чтобы преобразовать тип значения, вам нужно сопоставить значения из Any? Любой, выполнив бросок. Компилятор не может знать, что предикат, который вы передаете filter (), гарантирует, что все значения фильтрованной карты не равны нулю, поэтому он не может использовать вывод типа. Таким образом, ваш лучший et должен использовать

 val filtered: Map<String, Any> = map.filterValues { it != null }.mapValues { it -> it.value as Any } 

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

 fun filterNotNullValues(map: Map<String, Any?>): Map<String, Any> { val result = LinkedHashMap<String, Any>() for ((key, value) in map) { if (value != null) result[key] = value } return result } 

Компилятор просто не выполняет анализ типа достаточно глубоко, чтобы сделать вывод, что, например, input.filterValues { it != null } отфильтровывает null значения с карты, и, следовательно, результирующая карта должна иметь непустой тип значения. В принципе, может быть произвольный предикат с произвольным значением в терминах типов и nullability.

Нет специальной функции для фильтрации null значений из карты в stdlib (например, для .filterIsInstance<T>() существует .filterIsInstance<T>() ). Поэтому ваше самое простое решение – применить непроверенный бросок, сообщив компилятору, что вы уверены, что безопасность типа не нарушена:

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

См. Также: еще один вопрос с аналогичной проблемой is -check.