Kotlin - 在地图列表中附加元素 - 期望列表<Object>,找到列表<Kotlin.Unit>

Kotlin - Append element in a list from a map - Expecting List<Object>, Found List<Kotlin.Unit>

我有一个包含键和翻译的消息对象列表。

val messages = mutableListOf<Message>()

我想从这个邮件列表中获取翻译。

在简单地映射到 Translation 对象之前,我正在检查我的 Message 对象的特定属性,然后遍历另一个列表以将新的翻译添加到我的列表中。

Messages 由 4 个元素组成,我希望在遍历 messages.list 时总共有 6 个元素

得到:

预期:

代码:

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

我可以清楚地看到迭代正确完成但附加失败。

如何遍历地图中的列表,将 Translation 对象附加到同一列表并避免具有 Kotlin.Unit 类型?

Edit1:添加消息和翻译类

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)

既然要将一个事物映射到多个事物,就应该使用flatMap。在 flatMap 的 lambda 中,您可以 return 一个 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))
    }
}

您的 messages.map 调用将每条消息映射到内部 lambda 调用的结果:

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

else 部分很简单 - 只需将其映射到新的 Translation 对象。但在 if 部分它很棘手 - lambda 的 return 值是最后一行,即 message.list.forEachIndexed,其中 returns Unit - 不会存储 forEachIndexed 内发生的所有内容在任何地方,您只需创建和实例而不用它做任何事情