Как преобразовать список в карту с помощью Kotlin

#java #lambda #kotlin

#java #лямбда #kotlin

Вопрос:

Я пытаюсь создать карту из списка. Моя цель — сравнить два списка и найти различия между этими двумя списками. Затем я хочу создать карту, чтобы знать, в каком индексе я нашел различия.

Я сделал это на Java, не лучшим образом, на мой взгляд, но это работает.

 //I compare the two values for a given index, if value are the same, I set null in my result list
List<String> result = IntStream.range(0, list1.size()).boxed()
                .map(i -> list1.get(i) != list2.get(i) ? (list1.get(i)    " != "  list2.get(i)) : null)
                .collect(Collectors.toList());

//I filter all the null values, in order to retrieve only the differences with their index
Map<Integer, String> mapResult =
            IntStream.range(0, result.size())
            .boxed().filter(i-> null != result.get(i))
            .collect(Collectors.toMap(i -> i,result::get));
  

Это не оптимально, но работает. Если у вас есть предложения относительно этих строк кода, я с радостью ими воспользуюсь.

Я дважды пытался повторить подобное поведение в Kotlin, но мне не удалось использовать конструктор map(). (Я все еще изучаю Kotlin, я не очень знаком с ним).

Спасибо за вашу помощь.

Ответ №1:

Вы можете использовать zip функцию в коллекциях для соединения двух элементов. withIndex() Функция помогает превратить список в список пар индекса элемента и значения. Полное решение может быть следующим

 
    val list1 = listOf("a", "b", "c")
    val list2 = listOf("a", "B", "c")

    val diff : Map<Int, String> = list1.withIndex()
        .zip(list2) { (idx,a), b -> if (a != b) idx to "$a != $b" else null}
        .filterNotNull().toMap()
  

Обратите внимание, что zip функция выполняет итерации, пока есть элементы в обоих списках, она пропустит возможные остатки из любого из списков. Это можно исправить, добавив пустые элементы с помощью следующей функции:

 
fun <T> List<T>.addNulls(element: T, toSize: Int) : List<T> {
    val elementsToAdd = (toSize - size)
    return if (elementsToAdd > 0) {
        this   List(elementsToAdd) { element }
    } else {
        this
    }
}
  

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

Комментарии:

1. Спасибо, именно то, что мне было нужно!