Home > other >  I don't know how to sort by condition in scala
I don't know how to sort by condition in scala

Time:10-31

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.

  • Related