基于属性对象将列表的属性合并到另一个列表的属性

Merge properties of a list to another based on properties objects

我得到了 2 个包含 x 个对象的列表,例如:

data class Model(
    var token: String = "",
    var id: String = "",
    var name: String = "",
    var image: Int = 0,
) 

数组已初始化并填充,另一个列表有 x 个对象也包含第一个列表的对象,但它们的属性值不同!

我想做的是,如果第一个数组的属性相同,则用第二个数组更改第一个数组的属性object.name

var arr1 = ArrayList<Model>() // locale  
var arr2 = ArrayList<Model>() // from db 

例如我得到的第一个数组

[Model(name = "David", token = "" , image = 0)]

我得到的第二个数组

[Model(name = "David", token = "1asd5asdd851", image = 1)]

如何让第一个数组获取丢失的标记?

我尝试使用 .filter{}.map{}groupBy {} 几个小时,因为名称是唯一相同的属性,但我越来越困惑。

我们可以先使用 associateBy() 按名称对第二个数组进行分组,然后遍历第一个数组并重新分配属性:

val arr2ByName = arr2.associateBy { it.name }
arr1.forEach { item1 ->
    arr2ByName[item1.name]?.let { item2 ->
        item1.token = item2.token
        item1.image = item2.image
    }
}

或者,如果您不需要修改 arr1 中的项目,而是创建另一个数组并且您可以同时使用 arr1arr2 中的项目,那么它将是容易得多:

val arr3 = arr1.map { arr2ByName[it.name] ?: it }

一种可能的方法是使用 fold(),如下所示:

fun main(args: Array<String>) {
    val arr1 = listOf(Model(name = "David", token = "" , image = 0))
    val arr2 = listOf(Model(name = "David", token = "1asd5asdd851", image = 1))

    val mergedModels = arr2.fold(arr1) { localModels, dbModel ->
        localModels.map { localModel ->
            if (localModel.name == dbModel.name) localModel.copy(token = dbModel.token, image = dbModel.image)
            else localModel
        }
    }

    println(mergedModels)
}

如果你想重用 arr1 变量,那么你可以执行以下操作(但我仍会使用之前的选项):

fun main(args: Array<String>) {
    var arr1 = listOf(Model(name = "David", token = "" , image = 0))
    val arr2 = listOf(Model(name = "David", token = "1asd5asdd851", image = 1))

    arr1 = arr2.fold(arr1) { localModels, dbModel ->
        localModels.map { localModel ->
            if (localModel.name == dbModel.name) localModel.copy(token = dbModel.token, image = dbModel.image)
            else localModel
        }
    }

    println(arr1)
}