In Scala, how to use Ordering[T] with List.min or List.max and keep code readable

前端 未结 6 558
轮回少年
轮回少年 2020-12-23 20:58

In Scala 2.8, I had a need to call List.min and provide my own compare function to get the value based on the second element of a Tuple2. I had to write this kind of code:

6条回答
  •  离开以前
    2020-12-23 21:39

    You could always define your own implicit conversion:

    implicit def funToOrdering[T,R <% Ordered[R]](f: T => R) = new Ordering[T] {
      def compare(x: T, y: T) = f(x) compare f(y)
    }
    
    val list = ("a", 5) :: ("b", 3) :: ("c", 2) :: Nil
    
    list.min { t: (String,Int) => t._2 }  // (c, 2)
    

    EDIT: Per @Dario's comments.

    Might be more readable if the conversion wasn't implicit, but using an "on" function:

    def on[T,R <% Ordered[R]](f: T => R) = new Ordering[T] {
      def compare(x: T, y: T) = f(x) compare f(y)
    }
    
    val list = ("a", 5) :: ("b", 3) :: ("c", 2) :: Nil
    
    list.min( on { t: (String,Int) => t._2 } ) // (c, 2)
    

提交回复
热议问题