Home > Mobile >  Merge properties of a list to another based on properties objects
Merge properties of a list to another based on properties objects

Time:01-25

I got 2 lists with x objects inside , for example:

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

array is initialized and filled, the other list has x objects also that contains the objects of the first list but with different values in their properties!

what I want to do is to change the properties of the first array by the second one if they got the same object.name

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

the first array I got for example

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

the second array I got

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

How do I make the first array take the missing token?

I tried with .filter{} and with .map{}. groupBy {} for hours because Name is the only properties that are the same but I'm more and more confused.

CodePudding user response:

We can first group the second array by name using associateBy() and then iterate over first array and reassign properties:

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

Alternatively, if you don't need to modify items in arr1, but create another array and you can use items from both arr1 and arr2, then it will be much easier:

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

CodePudding user response:

One possible way would be to use fold() as follows:

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)
}

If you want to reuse arr1 variable then you can do the following (but I would still use the previous option):

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)
}
  •  Tags:  
  • Related