Lets say i have a list of Objects (Accounts) in my RoomDatabase. And when the application starts i request the Accounts from Server in order to Update the Accounts Table.
So i query the database, getting a
current: List<Account>
which is the existing accounts in the database
From the Server we have the news: List<Account>
list which is the updated Accounts
I want to find
- The elements from the news that exist in the current, in order to update them
- The elements from the news that don't exist in the current, in order to insert them
- The elements from the current that don't exist in the news, in order to delete them
Is there any extension function that can do that Job with an elegant and fast way, except the obvious that is to do one step at a time with the already known technique? (Loop in each list every time)
CodePudding user response:
You could use partition
I suppose
val current = listOf("hey", "hi", "wow")
val news = listOf("hi", "hey", "sup")
fun main() {
val (retain, discard) = current.partition { it in news }
val insert = news.filterNot { it in current }
println("Retain: $retain\nDiscard: $discard\nInsert: $insert")
}
>> Retain: [hey, hi]
>> Discard: [wow]
>> Insert: [sup]
"Elegant and fast" is subjective - is this less elegant?
val retain = current.filter { it in news }
val discard = current.filter { it !in news }
val insert = news.filter { it !in current }
it's arguably neater and easier to read - three conditions, described the exact same way.
Faster? Well that depends on the size of your lists, and you'd have to benchmark the solutions to see how much difference it makes (and if it's worth prioritising it over readability). Converting the lists to sets would give you a performance boost for the in
checks, but the conversion itself might be slower than the gains in lookup speed
CodePudding user response:
According on your answer - the most efficient way in your case is just drop your previous accounts from db and write new. Your backend data always a priority. Instead of many data manipulations(get from db, compare lists, insert and delete to new list), do just
- delete old accounts with delete method in your room dao.
- insert new accounts from your backend using insert method in dao.
Extension for this with coroutines:
suspend fun List<Account>.insertActual() = withContext(IO) {
yourDao.deleteAccounts()
yourDao.insertAccounts(this)
}