Let's assume i have a class with two instances:
class Car(val id: Int, val color: Color, val pistons: Int, val spoiler: Boolean) val audi = Car(1234, Color.BLUE, 8, false) val bmw = Car(4321, Color.WHITE, 6, false) Now i'd like to check equality for some properties (not all -> i'd use a data class in that case)
fun looksSimilar(a: Car, b: Car) = a.color == b.color && a.spoiler == b.spoiler I'm now looking for a method which does comparison:
- for more generic objects
Tand their properties - more idiomatic: no-one wants to read tons of equals-checks
- similarly fast
I've come up with the following proposal:
fun <T> Pair<T, T>.equalIn(vararg arguments: (T) -> Any?) = arguments.toList().all { it(first) == it(second) } which allows me to write the above check as
val looksSimilar = (audi to bmw).equalIn({it.color}, {it.spoiler}) Does anyone know a better (e.g. cleaner/faster) solution?
My usecase is the following:
I'm writing an Android App with multiple RecyclerView's (= fancy view to display lists)
Each RecyclerView has a ListAdapter (responsible for the underlying list)
Each ListAdapter requires a DiffUtil.ItemCallback (for comparing old & new Items & initiating appropiate changes in the view)
val callback = object : DiffUtil.ItemCallback<Car>() { override fun areItemsTheSame(oldItem: Car, newItem: Car): Boolean // usually checks for id, e.g. oldItem.id == newItem.id override fun areContentsTheSame(oldItem: Car, newItem: Car): Boolean // checks if two items look the same. // Used for fancy enter/exit animations afaik. // e.g. (oldItem to newItem).equalIn({it.color}, {it.spoiler}) }
.equalIn(Car::color, Car::spoiler). Otherwise, your way seems fine to me. Maybe it's a little awkward to require the intermediate Pair. Other than that, this is creating functional objects and arrays to do the check, so there's a bit of GC churn that you wouldn't have by using==comparisons directly.classyou usedata classthat is exactly the reason whydata classexist, it allows structural comparison by just sayinga == b, yourPistonswould also have to be a data class. And usually in the diff item callback theareItemsTheSameis the ids comparison and then on the content you useoldItem == newItemComparatorthat only handlesequals) so you can create an instance of it, configured how you like, and just use that for all your checks. You could pass in your property list during construction, to define all the checks it should do, and then you create it once - and you can have different variations if you need them