Как из списка пар ключ-значение получить числовой список с помощью extension функции в Kotlin
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Получение числового списка из Map с помощью Extension-функции в Kotlin
В Kotlin extension-функции позволяют расширять функциональность существующих классов без их модификации. Для преобразования списка пар "ключ-значение" (то есть Map) в числовой список можно создать несколько вариантов extension-функций в зависимости от конкретных требований.
Базовый подход: преобразование значений Map
Самый простой способ — создать extension-функцию для Map<K, V>, которая будет извлекать все значения и преобразовывать их в числовой список:
// Extension-функция для Map с любыми типами ключей и значений
fun <K, V : Number> Map<K, V>.toNumberList(): List<Number> {
return this.values.toList()
}
// Использование
val map = mapOf("a" to 1, "b" to 2.5, "c" to 3)
val numberList = map.toNumberList()
println(numberList) // [1, 2.5, 3]
Типобезопасные варианты
Часто требуется работать с конкретными числовыми типами. Вот несколько специализированных extension-функций:
// Для целых чисел
fun <K> Map<K, Int>.toIntList(): List<Int> {
return this.values.toList()
}
// Для чисел с плавающей точкой
fun <K> Map<K, Double>.toDoubleList(): List<Double> {
return this.values.toList()
}
// Универсальная функция с преобразованием типов
fun <K, V : Number> Map<K, V>.toListOfType(): List<V> {
return this.values.toList()
}
// Пример использования
val intMap = mapOf("x" to 10, "y" to 20, "z" to 30)
val intList = intMap.toIntList() // [10, 20, 30]
val doubleMap = mapOf("a" to 1.5, "b" to 2.7)
val doubleList = doubleMap.toDoubleList() // [1.5, 2.7]
Продвинутые сценарии с фильтрацией и преобразованием
В реальных задачах часто требуется дополнительная обработка данных:
// Только чётные числа
fun <K> Map<K, Int>.toEvenIntList(): List<Int> {
return this.values.filter { it % 2 == 0 }
}
// Числа больше определённого порога
fun <K> Map<K, Int>.toIntListAbove(threshold: Int): List<Int> {
return this.values.filter { it > threshold }
}
// Преобразование строк в числа (с обработкой ошибок)
fun <K> Map<K, String>.toSafeIntList(): List<Int> {
return this.values.mapNotNull { it.toIntOrNull() }
}
// Примеры использования
val scores = mapOf("Alice" to 85, "Bob" to 92, "Charlie" to 78)
val highScores = scores.toIntListAbove(80) // [85, 92]
val stringMap = mapOf("a" to "10", "b" to "20", "c" to "invalid")
val parsedList = stringMap.toSafeIntList() // [10, 20]
Работа с nullable значениями
Для обработки Map с nullable значениями можно создать такие extension-функции:
// Игнорирование null значений
fun <K, V : Number> Map<K, V?>.toNumberListIgnoreNulls(): List<V> {
return this.values.filterNotNull()
}
// Сохранение null значений
fun <K, V : Number> Map<K, V?>.toNumberListWithNulls(): List<V?> {
return this.values.toList()
}
// Пример
val nullableMap = mapOf("a" to 1, "b" to null, "c" to 3)
val withoutNulls = nullableMap.toNumberListIgnoreNulls() // [1, 3]
Сортировка и дополнительные операции
Extension-функции могут включать дополнительную логику:
// Отсортированный числовой список
fun <K, V : Comparable<V>> Map<K, V>.toSortedList(): List<V> {
return this.values.sorted()
}
// Сумма значений
fun <K> Map<K, Int>.sumValues(): Int {
return this.values.sum()
}
// Среднее значение
fun <K> Map<K, Int>.averageValues(): Double {
return this.values.average()
}
// Пример
val data = mapOf("Jan" to 100, "Feb" to 150, "Mar" to 200)
val sorted = data.toSortedList() // [100, 150, 200]
val total = data.sumValues() // 450
val avg = data.averageValues() // 150.0
Практический пример применения
Рассмотрим реальный кейс — обработка данных о продажах:
data class Sale(val productId: String, val amount: Double)
fun Map<String, Sale>.getAmountsAbove(limit: Double): List<Double> {
return this.values
.map { it.amount }
.filter { it > limit }
.sorted()
}
// Использование
val sales = mapOf(
"1" to Sale("p1", 100.0),
"2" to Sale("p2", 250.0),
"3" to Sale("p3", 50.0)
)
val highSales = sales.getAmountsAbove(75.0) // [100.0, 250.0]
Ключевые преимущества подхода
- Читаемость кода — extension-функции делают код более декларативным и понятным
- Переиспользование — логика инкапсулируется в одной функции
- Безопасность типов — компилятор Kotlin проверяет типы на этапе компиляции
- Интеграция с остальным кодом — extension-функции прекрасно работают с другими возможностями Kotlin
- Расширяемость — легко добавлять новую функциональность без изменения исходных классов
Рекомендация: При создании extension-функций для работы с Map важно чётко определить контракт функции — что именно она возвращает и при каких условиях. Для сложных преобразований стоит добавлять обработку исключительных ситуаций и предоставлять документирующие комментарии.