【问题标题】:parse and replace a list of object in kotlin解析和替换 kotlin 中的对象列表
【发布时间】:2018-03-21 19:46:45
【问题描述】:

我目前有一个对象列表定义为:

fun updateList(tools: List<Tool>, updateTools: List<Updated>){
... code below
}

Tool 数据类定义为:

data class Tool(
    var id: String = ""
    var description: String = ""
    var assignedTo: String = ""
)

Updated 数据类定义为:

data class Updated(
    var id: String = ""
    var assignedTo: String = ""
)

基本上,我解析列表updateTools,如果我在tools 中找到id 匹配项,我将Tool 类型对象中tools 中的assignedTo 字段更新为@987654332 中的字段@

fun updateList(tools: List<Tool>, updateTools: List<Updated>){
    updateTools.forEach{
        val idToSearch = it.id
        val nameToReplace = it.name
        tools.find(){
            if(it.id == idToSearch){it.name=nameToReplace}
        }
    }
    return tools
}

它不工作,但我不知道如何使它更容易工作。我刚开始使用kotlin,我觉得这不是做它的好方法 有什么想法吗?

谢谢

【问题讨论】:

    标签: list foreach kotlin


    【解决方案1】:

    首先:

    • 您没有分配assignedTo,您分配的是name...
    • 在传递给find的谓词中,其中
      • 应该返回一个Boolean值来过滤元素,并且
      • 应该不会有任何副作用
      • 这些应该稍后通过调用 forEach 来完成。

    此外,数据类的构造函数参数是普通参数,因此它们之间需要逗号!

    您的最后一个代码块,更正后是:

    updateTools.forEach {
        val idToSearch = it.id
        val nameToReplace = it.name
        tools.find { it.id == idToSearch }.forEach { it.assignedTo = nameToReplace }
    }
    return tools
    

    我会这样做(更短):

    updateTools.forEach { u -> tools.filter { it.id == u.id }.forEach { it.assignedTo = u.name } }
    

    这会遍历每次更新,过滤 tools 以查找具有正确 ID 的工具,并设置每个工具的名称。

    我使用forEach,因为filter 返回List&lt;Tool&gt;


    如果你能保证id 是唯一的,你可以这样做:

    updateTools.forEach { u -> tools.find { it.id == u.id }?.assignedTo = u.name }
    

    firstOrNull 返回匹配条件的第一个元素,如果没有,则返回 null 编辑: 似乎 find 是 em> firstOrNull - 它的实现只是调用firstOrNull

    如果左操作数是null,则?.安全调用运算符返回null,否则,它调用方法。

    对于= 和其他返回Unit 的运算符(即void,无),如果左操作数为空,则使用安全调用运算符不会执行任何操作。

    如果我们将它们结合起来,它会有效地设置与此条件匹配的第一个元素的名称。

    【讨论】:

    • 这是最具描述性的答案,非常感谢@moira
    【解决方案2】:

    首先,您的数据类中的属性后面缺少逗号,因此应该是:

    data class Tool(
        var id: String = "",
        var description: String = "",
        var assignedTo: String = ""
    )
    
    data class Updated(
        var id: String = "",
        var assignedTo: String = ""
    )
    

    至于第二个问题,可能有很多方法可以做到这一点,但我只是更正了你的想法:

    fun updateList(tools: List<Tool>, updateTools: List<Updated>): List<Tool> {
        updateTools.forEach{ ut ->
            tools.find { it.id == ut.id }?.assignedTo = ut.assignedTo
        }
        return tools
    }
    

    您可以为forEach 命名参数并在循环的其余部分使用它,而不是为变量赋值。

    【讨论】:

      猜你喜欢
      • 2019-04-20
      • 2015-01-01
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多