Easy idiomatic way to define Ordering for a simple case class

前端 未结 6 849
挽巷
挽巷 2020-11-30 17:34

I have a list of simple scala case class instances and I want to print them in predictable, lexicographical order using list.sorted, but receive \"No implicit O

6条回答
  •  日久生厌
    2020-11-30 17:47

    To summarize, there are three ways to do this:

    1. For one-off sorting use .sortBy method, as @Shadowlands have showed
    2. For reusing of sorting extend case class with Ordered trait, as @Keith said.
    3. Define a custom ordering. The benefit of this solution is that you can reuse orderings and have multiple ways to sort instances of the same class:

      case class A(tag:String, load:Int)
      
      object A {
        val lexicographicalOrdering = Ordering.by { foo: A => 
          foo.tag 
        }
      
        val loadOrdering = Ordering.by { foo: A => 
          foo.load 
        }
      }
      
      implicit val ord = A.lexicographicalOrdering 
      val l = List(A("words",1), A("article",2), A("lines",3)).sorted
      // List(A(article,2), A(lines,3), A(words,1))
      
      // now in some other scope
      implicit val ord = A.loadOrdering
      val l = List(A("words",1), A("article",2), A("lines",3)).sorted
      // List(A(words,1), A(article,2), A(lines,3))
      

    Answering your question Is there any standard function included into the Scala that can do magic like List((2,1),(1,2)).sorted

    There is a set of predefined orderings, e.g. for String, tuples up to 9 arity and so on.

    No such thing exists for case classes, since it is not easy thing to roll off, given that field names are not known a-priori (at least without macros magic) and you can't access case class fields in a way other than by name/using product iterator.

提交回复
热议问题