#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