I wanted to sort like this but I get an error. How can we improve?
If the integers containedenter code here
in keys are
If 1, order by name (Ordering.String)
If 2 then order with highest English score (Ordering.Int.reverse)
If 3 then order with highest math score (Ordering.Int.reverse)
If 4, order with highest science score (Ordering.Int.reverse)
If 5, order by exam date (oldest to newest)enter code here
Sort by. Any other numbers (1-5) are ignored.
If multiple keys are specified, they are compared in order from the beginning of Seq.
If kesy is empty, it is returned without sorting.
Also, if each item has a minus sign, it is sorted in reverse order.
If the same number is specified multiple times in keys, the second and subsequent specifications are ignored.
For example, Seq(-10, 5, 4, 0, -1, 2, 5, 1) is treated as Seq(5, 4, -1, 2).
Example) If keys is Seq(-5, 1, 2, 3, 4):
Compare in descending order of date, if same, sort by name, if same, sort by highest score in English, math, and science.
object OptionAnswer {
case class Score(
name: String,
english: Int,
math: Int,
science: Int,
date: LocalDate
)
def main(args: Array[String]): Unit = {
val scoreOfAlice = Score(name = "Alice", english = 77, math = 74, science = 26, date = LocalDate.of(2020, 1, 30))
val scoreOfBob = Score(name = "Bob", english = 100, math = 74, science = 14, date = LocalDate.of(2020, 1, 26))
val scoreOfCharlie = Score(name = "Charlie", english = 100, math = 74, science = 99, date = LocalDate.of(2020, 1, 26))
val scoreOfDave = Score(name = "Dave", english = 50, math = 81, science = 88, date = LocalDate.of(2020, 1, 30))
val scoreSeq: Seq[Score] = List(scoreOfAlice,scoreOfBob,scoreOfCharlie,scoreOfDave)
val keys = Seq(-5, 1, 2, 3, 4)
println(sortScore(scoreSeq, keys))
}
def sortScore(scoreSeq: Seq[Score], keys: Seq[Int]): Seq[Score] = {
val keys_set = keys.toSet
keys_set match{
case 1 => scoreSeq.sortBy(score => score.name)
case 2 => scores.sortBy(score => -score.english)
case 3 => scores.sortBy(score => -score.math)
case 4 => scores.sortBy(score => -score.science)
case -1 => scoreSeq.sortBy(score => -score.name)
case -2 => scores.sortBy(score => score.english)
case -3 => scores.sortBy(score => score.math)
case -4 => scores.sortBy(score => score.science)
case _ => score
}
CodePudding user response:
You need to start by writing the function to sort by a single key:
def sortByKey(scores: Seq[Score], key: Int): Seq[Score] = {
val res = math.abs(key) match {
case 1 => scores.sortBy(_.name)
case 2 => scores.sortBy(-_.english)
case 3 => scores.sortBy(-_.math)
case 4 => scores.sortBy(-_.science)
case _ => scores
}
if (key < 0) {
res.reverse
} else {
res
}
}
Then you can just use foldLeft
to apply the sort to a list of keys:
def sortScores(scores: Seq[Score], keys: Seq[Int]): Seq[Score] =
keys.distinct.reverse.foldLeft(scores)(sortByKey)
The keys are distinct
to remove duplicates and in reverse
because the most important key is the one applied last.
The alternative is to use the list of keys to create a single complex ordering function but I'll leave someone else to write that solution.