I have two lists that look roughly like this:
val localList = listOf(
HumanValue(id = "abc", gamesPlayed=7, gamesWon=4, removed=false),
HumanValue(id = "abcd", gamesPlayed=1, gamesWon=0, removed=false),
HumanValue(id = "abcde", gamesPlayed=6, gamesWon=3, removed=false),
HumanValue(id = "abcdef", gamesPlayed=12, gamesWon=12, removed=false)
)
val remoteList = listOf(
HumanValue(id = "abc", gamesPlayed=12, gamesWon=7, removed=false),
HumanValue(id = "abcd", gamesPlayed=1, gamesWon=0, removed=false),
HumanValue(id = "abcde", gamesPlayed=6, gamesWon=3, removed=true),
HumanValue(id = "abcdef", gamesPlayed=12, gamesWon=12, removed=false),
HumanValue(id = "abcdefg", gamesPlayed=0, gamesWon=0, removed=false)
)
What I want is the most up to date list to be the canonical list, so whichever item has the highest number of games would be the most up to date and thus the canonical one. The default state of each one is also that it hasn't been removed so if it has been removed that has been done intentionally and is thus canonical.
I could go through each one in the longer list with a forEach, then add the one with the highest gamesPlayed to a third list, then set each of these lists to that third list, but that doesn't feel best practice/idiomatic/efficient etc.
Is there another way to do this for instance with kotlin methods such as mapping or flatmapping or something else?
Edit: This is the best way I've come up with to do it. Looks pretty bad to me:
suspend fun compareDBs() {
if ((localDeck.value?.size == remoteDeck.value?.size) && (localDeck.value?.toSet() == remoteDeck.value?.toSet())) { return }
else {
val diff1: MutableList<HumanValue> = mutableListOf(localDeck.value?.minus(arrayOf(remoteDeck).toSet())) as MutableList<HumanValue>
val diff2 = remoteDeck.value?.minus(arrayOf(localDeck).toSet()) as MutableList<HumanValue>
val listOfDifferences = mutableListOf<HumanValue>()
listOfDifferences.addAll(diff1)
listOfDifferences.addAll(diff2)
listOfDifferences.forEach {diffValue ->
val localVersion = localDeck.value?.filter { it.id == diffValue.id }
val remoteVersion = remoteDeck.value?.filter { it.id == diffValue.id }
if (!localVersion.isNullOrEmpty() && !remoteVersion.isNullOrEmpty()) {
if (localVersion[0].gamesPlayed > remoteVersion[0].gamesPlayed) { localIsCanonical() }
else { remoteIsCanonical() }
}
else {
if (localVersion.isNullOrEmpty()) { remoteIsCanonical() }
else if (remoteVersion.isNullOrEmpty()) { localIsCanonical() }
}
}
}
}
This is just one idea.
val combinedList = localList.plus(remoteList)
val mapOfIds = combinedList.groupBy { humanValue ->
humanValue.id
}
val finalList = mapOfIds.values.map { humanValuesForId ->
humanValuesForId.maxByOrNull { it.gamesPlayed }
}
The final code could look like this:
val finalList = localList
.plus(remoteList)
.groupBy { humanValue ->
humanValue.id
}
.values
.map { humanValuesForId ->
humanValuesForId.maxByOrNull { it.gamesPlayed }
}