我需要编写一个对Seq[T]
对象执行排序的通用代码。我知道赢了可以执行排序操作,直到我们知道base class
及其attributes
。在看了这个answer后,我采用了这个代码,我的要求是尽可能多地处理自定义数据类型。
case class Country(name: String, id : Int)
type CountrySorter = (Country, Country) => Boolean
def byName : CountrySorter = (c1:Country, c2:Country) => c1.name < c2.name
def byId : CountrySorter = (c1:Country, c2:Country) => (c1.id < c2.id)
val sortingMap = Map[String, CountrySorter](
"sortByCountryName" -> byName ,
"soryByCountryId" -> byId
)
函数调用
def sort[T]( input : Seq[T], criteria : String) : Seq[T] = {
input.sortWith(sortingMap(criteria))
}
input.sortWith(sortingMap(标准)) 在这里我收到错误,因为sortWith
函数只接受Country
类型,而不是{{1 }类型。
答案 0 :(得分:3)
使用带有字符串类型键的SELECT
ev.name,
LISTAGG(user_name, ', ') WITHIN GROUP ( ORDER BY user_name DESC ) "Users"
FROM events ev
LEFT JOIN users u ON u.birthday >= ev.datestart AND u.birthday <= ev.dateend
GROUP BY ev.name;
对国家/地区进行排序很容易出错。更好的选择是通过Map
类型类利用Scala中的排序机制。
你可以像这样使用它:
Ordering[A]
这里的问题是在范围内有正确的顺序。您可以在范围内创建单个临时排序:
def sort[T](input : Seq[T])(implicit order: Ordering[T]): Seq[T] = {
input.sorted
}
您可以在案例类的配套中定义顺序并明确导入它:
def main(args: Array[String]): Unit = {
implicit val byIdOrdering = Ordering.by((country: Country) => country.id)
val countries: Seq[Country] = ???
sort(countries)
}
如果您有这样的订购规则,也可以使用low priority implicits trick:
object Country {
implicit val byIdOrdering: Ordering[Country] =
Ordering.by((country: Country) => country.id)
implicit val byNameOrdering: Ordering[Country] =
Ordering.by((country: Country) => country.name)
}
import Country.byNameOrdering
def main(args: Array[String]): Unit = {
val countries: Seq[Country] = ???
sort(countries)
}
如果需要,甚至可以明确传递顺序:
trait LowPriorityCountryImplicits {
implicit val byNameOrdering: Ordering[Country] =
Ordering.by((country: Country) => country.name)
}
object HighPriorityCountryImplicits extends LowPriorityCountryImplicits {
implicit val byIdOrdering: Ordering[Country] =
Ordering.by((country: Country) => country.id)
}
import HighPriorityCountryImplicits._
def main(args: Array[String]): Unit = {
val countries: Seq[Country] = ???
sort(countries)
}
答案 1 :(得分:2)
如果您想使用sortWith
case class Country(name: String, id : Int)
type Sorter[T] = (T, T) => Boolean
type CountrySorter = Sorter[Country]
def byName : CountrySorter = (c1, c2) => c1.name < c2.name
def byId : CountrySorter = (c1, c2) => c1.id < c2.id
def sort[T](input: Seq[T], sorter: Sorter[T]): Seq[T] = {
input.sortWith(sorter)
}
val countries = List(Country("Australia", 61), Country("USA", 1), Country("France", 33))
sort(countries, byName)
// res1: Seq[Country] = List(Country(Australia,61), Country(France,33), Country(USA,1))
sort(countries, byId)
// res2: Seq[Country] = List(Country(USA,1), Country(France,33), Country(Australia,61))
答案 2 :(得分:0)
使用上述答案后,我已通过以下代码
满足此要求通用特征,它是所有子案例类的父级,即仅包含执行排序的字段
sealed trait Generic{
def name : String = ???
def id : Int = ???
def place : String = ???
}
//case class which need to be sorted
case class Capital(
countryName : String,
override val id: Int,
override val place:String
) extends Generic
case class Country(
override val name: String,
override val id: Int
) extends Generic
排序类型
type Sorter[T] = (T, T) => Boolean
type CountrySorter = Sorter[Generic]
type CapitalSorter = Sorter[Generic]
排序订单
def byName : CountrySorter = (c1, c2) => c1.name < c2.name
def byId : CountrySorter = (c1, c2) => c1.id < c2.id
def byPlace : CapitalSorter = (s1, s2) => s1.place > s2.place
排序方法
def sort[T](input: Seq[T], sorter: Sorter[T]): Seq[T] = {
input.sortWith(sorter)
}
用于保存具有名称的排序顺序的数据结构。
val mapper = Map[String, Sorter[Generic]](
"name" -> byName,
"id" -> byId,
"place" -> byPlace
)
输入
val countries = List(Country("Australia", 61), Country("USA", 1), Country("France", 33))
val headQuaters = List(
Capital("Australia", 61, "Melbourne"),
Capital("America", 1, "New York"),
Capital("France", 33, "Paris"),
Capital("India", 65, "New Delhi")
)
输出
println(sort(countries,mapper("id")))
//List(Country(USA,1), Country(France,33), Country(Australia,61))
println(sort(headQuaters , mapper("place")))
//List(Capital(France,33,Paris), Capital(America,1,New York), Capital(India,65,New Delhi), Capital(Australia,61,Melbourne))