按多个字段排序的Scala
这个问题可能很愚蠢,但我找不到一个例子,也弄不明白 我想按姓氏、名和中间名的顺序比较两个按多个字段排序的Scala,scala,Scala,这个问题可能很愚蠢,但我找不到一个例子,也弄不明白 我想按姓氏、名和中间名的顺序比较两个Person类。这是一种大脑死亡的方式: def compare(that: Person): Int = { val last: Int = lastName.compare(that.lastName) if (last != 0) last else { val first: Int = firstName.compare(that.firstName) if (first
Person
类。这是一种大脑死亡的方式:
def compare(that: Person): Int = {
val last: Int = lastName.compare(that.lastName)
if (last != 0) last
else {
val first: Int = firstName.compare(that.firstName)
if (first != 0) first
else middleName.compare(that.middleName)
}
我知道有一些更聪明的方法可以做到这一点(可能是使用订购),但我无法确定
托德
当我意识到如何按顺序访问正确的东西时,我就明白了这一点
def compare(that: Person): Int = {
Ordering.Tuple3(Ordering.String, Ordering.String, Ordering.String).compare(
(lastName, firstName, middleName),
(that.lastName, that.firstName, that.middleName))
}
我很确定我可以用更少的显式词,但这很有效,而且相当紧凑。选项1:糟糕
使用sortBy
方法,这可能非常简单:
case class Person(first: String, middle: String, last: String)
val personList = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))
personList.sortBy{ case Person(f,m,l) => (l,f,m) }
选项2:延期订购[人]
通过扩展Ordered[Person]
,类将知道如何对自身进行排序,因此我们可以免费获得排序
、min
和max
:
case class Person(first: String, middle: String, last: String) extends Ordered[Person] {
def compare(that: Person): Int =
(last compare that.last) match {
case 0 =>
(first compare that.first) match {
case 0 => middle compare that.middle
case c => c
}
case c => c
}
}
val personList = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))
personList.sorted
personList.min
personList.max
选项3:隐式排序
如果您使用隐式的排序
,那么您将得到排序
、min
等,而不会将特定的排序绑定到原始类。这种分离可能很方便,也可能很烦人,这取决于您的具体情况
case class Person(first: String, middle: String, last: String)
implicit val ord = new Ordering[Person] {
def compare(self: Person, that: Person): Int =
(self.last compare that.last) match {
case 0 =>
(self.first compare that.first) match {
case 0 => self.middle compare that.middle
case c => c
}
case c => c
}
}
val personList = List(Person("john", "a", "smith"), Person("steve", "x", "scott"), Person("bill", "w", "smith"))
personList.sorted
personList.min
personList.max
如果您使用的是scala 2.13+,则可以使用Ordering.by
和orElseBy
。这是相当明确的
案例类人物(第一个:字符串,中间:字符串,最后一个:字符串)
隐式val排序:排序[Person]=按[Person,String]排序(u.first)
.Orelsby(中间)
.Orelsby(u.last)
val list=列表(人物(“约翰”、“a”、“史密斯”)、人物(“史蒂夫”、“x”、“斯科特”)、人物(“比尔”、“w”、“史密斯”))
list.sorted
一旦我发现StringOrdering
是一种特性,而不是一个目标,我就知道怎么做了。参见上文。this:personList.sortBy{case Person(f,m,l)=>(l,f,m)}看起来有点像魔术。如果您想使用元组技巧反转其中一个字段(即字符串)的顺序,该怎么办?有可能吗?这很不错,但只在2.13开时才有。