Котлин — Добавить элемент в список из карты — Ожидающий список, Найденный список

#list #dictionary #kotlin #foreach #iterator

Вопрос:

У меня есть список объектов сообщений, содержащий ключи и переводы.

 val messages = mutableListOf<Message>()
 

Из этого списка сообщений я хотел бы получить переводы из него.

Прежде чем просто сопоставить с Translation объектом, я проверяю определенный атрибут своего Message объекта и просматриваю дополнительный список, чтобы добавить новые переводы в свой список.

Сообщения состоят из 4 элементов, и я ожидаю , что при повторении messages.list , всего будет 6 элементов

Получил:

  • Элемент[0] (разблокировка=ложь): Перевод(сообщение.ключ)
  • Элемент[1] (разблокировка=true): kotlin.Unit
  • Элемент[2] (разблокировка=true): kotlin.Unit
  • Элемент[3] (разблокировка=ложь): Перевод(сообщение.ключ)

Ожидаемый:

  • Элемент[0] (разблокировка=ложь): Перевод(сообщение.ключ)
  • Элемент[1] (разблокировка=true): Перевод(«разблокировка»)
  • Элемент[2] (разблокировка=true): Перевод(«разблокировка»)
  • Элемент[3] (разблокировка=true): Перевод(«разблокировка»)
  • Элемент[4] (разблокировка=true): Перевод(«разблокировка»)
  • Элемент[5] (разблокировка=ложь): Перевод(сообщение.ключ)

Код:

 val translationList = messages.map { message ->
            if (message.unlock == "true") {
                message.list.forEachIndexed { index, item ->
                    Translation("unlock")
                }
            }
            else {
                    Translation(message.key)
            }
 

Я ясно вижу, что итерация выполнена правильно, но добавление не выполняется.

Как я могу повторить список на карте, который добавит объект перевода в этот же список, и избежать использования Котлина.Тип устройства?

Правка1: Добавление классов сообщений и переводов

 data class Message(@JacksonXmlProperty(localName = "unlock", isAttribute = true)
                   val unlock: String? = null,
                   @JacksonXmlProperty(localName = "key")
                   val key: String? = null,
                   @JacksonXmlProperty(localName = "list")
                   val list: MutableList<String>? = null,
                   @JacksonXmlElementWrapper(useWrapping = true)
                   @JacksonXmlProperty(localName = "translation")
                   val translation: Translation? = null)

data class Translation(@JacksonXmlProperty(localName = "type", isAttribute = true)
                       val type: String? = null,
                       @JacksonXmlProperty(localName = "innerText")
                       @JacksonXmlText
                       val text: String? = null)
 

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

1. @Sweeper только что добавил некоторые уточнения. На самом деле я анализирую пользовательский XML-файл, в котором есть свойства сообщений и перевода.

2. Просто исправил Message класс 🙂

Ответ №1:

Поскольку вы хотите сопоставить одну вещь с несколькими вещами, вам следует использовать flatMap . В лямбде flatMap вы можете вернуть Iterable то , на что вы хотите сопоставить каждый элемент.

 val translationList = messages.flatMap { message ->
    // you might want to use a Bool for message.unlock instead :)
    if (message.unlock == "true") {
        // we transform each element of message.list into a translation
        // forEach gives you Unit, map gives you the transformed list
        message.list.map { Translation("unlock") }
    }
    else {
        listOf(Translation(message.key))
    }
}
 

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

1. Отлично, вот и все ! Просто не использовал правильный инструмент. Спасибо за это быстрое решение !

Ответ №2:

ваш messages.map вызов сопоставляет каждое сообщение с результатами внутреннего лямбда-вызова:

         message ->
            if (message.unlock == "true") {
                message.list.forEachIndexed { index, item ->
                    Translation("unlock")
                }
            }
            else {
                    Translation(message.key)
            }
 

Другая часть проста — просто сопоставьте ее с новым объектом перевода. но в части «если» это сложно — возвращаемое значение лямбды — это последняя строка message.list.forEachIndexed , которая возвращает единицу измерения-все , что происходит внутри forEachIndexed, нигде не хранится, вы просто создаете и экземпляр и ничего с ним не делаете

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

1. Не могли бы вы предложить использовать a return@forEachIndexed ?

2. Я бы предложил использовать flatMap , как предложил @Sweeper