android - 在 Kotlin 中检查两个对象的某些(不是全部)属性是否相等的惯用方法

假设我有一个包含两个实例的类:

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)

现在我想检查一些属性的相等性(不是全部 -> 在这种情况下我会使用数据类)

fun looksSimilar(a: Car, b: Car) = a.color == b.color && a.spoiler == b.spoiler

我现在正在寻找一种进行比较的方法:

  • 对于更通用的对象 T 及其属性
  • 更地道:没有人愿意阅读大量的平等检查
  • 同样快

我提出了以下建议:

fun <T> Pair<T, T>.equalIn(vararg arguments: (T) -> Any?) =
    arguments.toList().all { it(first) == it(second) }

这让我可以把上面的支票写成

val looksSimilar = (audi to bmw).equalIn({it.color}, {it.spoiler})

有人知道更好(例如更清洁/更快)的解决方案吗?


我的用例如下:

我正在编写一个包含多个 RecyclerView 的 Android 应用程序(= 用于显示列表的精美 View )

每个RecyclerView都有一个ListAdapter(负责底层列表)

每个 ListAdapter 都需要一个 DiffUtil.ItemCallback(用于比较新旧项目以及在 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})
}

最佳答案

在浏览StackOverflow history的时候,又发现了这个问题,脑子里痒痒的,所以想了一下。我仍然坚持我的观点,我更喜欢明确的 if 检查(更容易理解 IMO,性能最快),但如果我必须使用扩展函数来做,我宁愿使用列表而不是一对(允许超过两个输入),我会在调用站点使用 lambda 的引用语法,使其更加简洁:

fun <T> List<T>.equalIn(vararg arguments: (T) -> Any?): Boolean {
    if (isEmpty()) return false
    val argumentsList = arguments.toList()
    return all { item -> argumentsList.all { it(item) == it(first()) } }
}

fun main() {
    val audi = Car(1234, Color.BLUE, 8, false)
    val bmw = Car(4321, Color.BLUE, 6, false)
    println(listOf(audi, bmw).equalIn(Car::color, Car::spoiler))
}

https://stackoverflow.com/questions/65253783/

相关文章:

c# - HttpClient : This instance has already starte

macos - M1 MAC 的 opencv 问题 - OpenCV imshow 不起作用

c# - EFCore5,使用 FromSqlRaw 和 [Owned] 属性

reactjs - 如何强制更新功能组件?

python - 如何将路径参数转发到 VPC 链路端点?

docker - 如何在 VSCode devcontainer 中使用 minikube?

typescript - 是否可以修改 TypeScript 中文字的推断类型?

php - 仅显示 MySQL 列值计数

c# - 使用 Lamar 注入(inject)运行时对象

ansible - 我怎样才能访问另一台服务器的ansible facts?