Min/max with Option[T] for possibly empty Seq?

后端 未结 10 954
别那么骄傲
别那么骄傲 2021-01-31 14:03

I\'m doing a bit of Scala gymnastics where I have Seq[T] in which I try to find the \"smallest\" element. This is what I do right now:

val leastOrNo         


        
10条回答
  •  失恋的感觉
    2021-01-31 14:36

    How about this?

    import util.control.Exception._
    allCatch opt seq.minBy(_.something)
    

    Or, more verbose, if you don't want to swallow other exceptions:

    catching(classOf[UnsupportedOperationException]) opt seq.minBy(_.something)
    

    Alternatively, you can pimp all collections with something like this:

    import collection._
    
    class TraversableOnceExt[CC, A](coll: CC, asTraversable: CC => TraversableOnce[A]) {
    
      def minOption(implicit cmp: Ordering[A]): Option[A] = {
        val trav = asTraversable(coll)
        if (trav.isEmpty) None
        else Some(trav.min)
      }
    
      def minOptionBy[B](f: A => B)(implicit cmp: Ordering[B]): Option[A] = {
        val trav = asTraversable(coll)
        if (trav.isEmpty) None
        else Some(trav.minBy(f))
      }
    }
    
    implicit def extendTraversable[A, C[A] <: TraversableOnce[A]](coll: C[A]): TraversableOnceExt[C[A], A] =
      new TraversableOnceExt[C[A], A](coll, identity)
    
    implicit def extendStringTraversable(string: String): TraversableOnceExt[String, Char] =
      new TraversableOnceExt[String, Char](string, implicitly)
    
    implicit def extendArrayTraversable[A](array: Array[A]): TraversableOnceExt[Array[A], A] =
      new TraversableOnceExt[Array[A], A](array, implicitly)
    

    And then just write seq.minOptionBy(_.something).

提交回复
热议问题