Reputation: 3
I have just started to learn Kotlin. I have two objects and I need to compare them. I only want list of cars with changed name (I want to do update garage object in database with new value when it's changed)
Object one:
{
"name": "Tom's garage"
"brands": [
{
"name": „Volkswagen”,
"cars": [
{
"id": „1”,
„name”: „Golf”
},
{
"id": „2”,
„name”: „Tiguan”
}
]
},
{
"name": „Audi”,
"cars": [
{
"id": „3”,
„name”: „A3”
},
{
"id": „4”,
„name”: „A4”
}
]
}
]
}
Object two:
{
"name": "Tom's garage"
"brands": [
{
"name": „Volkswagen”,
"cars": [
{
"id": „1”,
„name”: „Golf”
},
]
},
{
"name": „Audi”,
"cars": [
{
"id": „3”,
„name”: „A5””
},
]
}
]
}
So in output I want only list of cars with changed name (Audi A3 to Audi A5) in the garage.
[
{
"name": „Audi”,
"cars": [
{
"id": „3”,
„name”: „A5””
},
]
}
]
That's what I wrote, but I am not happy with my code. Can you suggest me better kotlin solution?
fun findDiff(current: Garage, updated: Garage): List<Car> {
val carsMap = current.brands.map {
brand -> brand.name to brand.cars.map { car -> car.id to car }.toMap()
}.toMap()
val output = arrayListOf<Car>()
for (brand in updated.brands) {
for (car in brand.cars) {
currentSettingsMap[brand.name]?.get(car.id)?.
let { currentCar ->
if (currentCar.name != car.name) {
output.add(car)
}
}
}
}
return output
}
Model:
class Garage(
val name: String
val brands: List<Brand> = emptyList()
)
class Brand(
val name: String,
val cars: List<Car> = emptyList()
)
class Car(
val id: Int,
val name: String
)
It's learning example, does not have to make any sense.
Upvotes: 0
Views: 87
Reputation: 9672
fun findDiff(current: Garage, updated: Garage): List<Car> {
// preparing a map for fast search
val currentCars = current.brands
.flatMap { it.cars } // list of all cars in "current" garage
.associateBy { it.id } // car.id -> car
return updated.brands.asSequence()
.flatMap { it.cars } // list of all cars in "updated" garage
.filter { it.id in currentCars } // we remove cars that are not in the "current" garage
.filter { it.name != currentCars.getValue(it.id).name } // filtering cars with the same id and different names
.toList()
}
Upvotes: 5