Sorting 将参数排序为变量
我有一个方法,需要以多种可能的方式对集合进行排序。与多次调用Sorting 将参数排序为变量,sorting,lambda,collections,kotlin,Sorting,Lambda,Collections,Kotlin,我有一个方法,需要以多种可能的方式对集合进行排序。与多次调用myCollection.sortedBy不同,我希望将传递给sortedBy的lambda作为变量,然后将该变量传递给一个调用sortedBy。但是,我无法确定lambda变量应该具有的类型。请记住,“按字段排序”可能有不同的类型(但它们显然都是可比较的) 以下是我的问题的简化版本: data class Person(val name: String, val age: Int) enum class SortBy { N
myCollection.sortedBy
不同,我希望将传递给sortedBy
的lambda作为变量,然后将该变量传递给一个调用sortedBy
。但是,我无法确定lambda变量应该具有的类型。请记住,“按字段排序”可能有不同的类型(但它们显然都是可比较的)
以下是我的问题的简化版本:
data class Person(val name: String, val age: Int)
enum class SortBy {
NAME, AGE
}
fun main(args: Array<String>) {
val people = listOf(Person("John", 30), Person("Mary", 20))
val sort = SortBy.NAME
val comparator = when (sort) {
SortBy.NAME -> { p: Person -> p.name }
SortBy.AGE -> { p: Person -> p.age }
}
// the line below won't compile
people.sortedBy(comparator).forEach(::println)
}
数据类人员(val name:String,val age:Int)
枚举类排序{
姓名、年龄
}
趣味主线(args:Array){
val people=listOf(个人(“约翰”,30岁),个人(“玛丽”,20岁))
val sort=SortBy.NAME
val比较器=何时(排序){
SortBy.NAME->{p:Person->p.NAME}
SortBy.AGE->{p:Person->p.AGE}
}
//下面这行代码无法编译
people.sortedBy(comparator).forEach(::println)
}
有什么想法吗?问题是两个lambda有非常不同的类型,因此变量
comparator
的类型被简单地推断为Any
,这是第一个常见的超类型。如果您需要能够为该变量分配任意一个lambda,则该变量没有其他类型(除了Any?
)
然后,根据您得到的结果(一个(Person)->Int
或一个(Person)->String
),sortedBy
方法必须以某种方式推断其类型参数,这在处理这两种情况时同样是不可能的
然而,有一个解决办法。您可以在不同的
分支中创建Comparator
实例,而不是在分支中创建Comparator
实例,该分支包装了将人员
实例进行比较的特定类型,函数为:
val comparator: Comparator<Person> = when (sort) {
SortBy.NAME -> compareBy { it.name }
SortBy.AGE -> compareBy { it.age }
}
您可以简单地使用属性引用
val people = listOf(Person("John", 30), Person("Mary", 20))
val sort = Person::age
people.sortedBy(sort).forEach(::println)
谢谢这非常有效。我以前不知道compareBy
。关键是让变量sort
能够以不同的类型保存Person::age
、Person::name
等。这就是为什么我的示例在
场景中出现了(真实场景比只按一个字段进行硬编码排序更复杂)。这种解决方案在那种情况下行不通。
val people = listOf(Person("John", 30), Person("Mary", 20))
val sort = Person::age
people.sortedBy(sort).forEach(::println)