diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2013-07-06 21:23:24 -0700 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2013-07-06 21:23:24 -0700 |
commit | 9e064f783e7ee42b9d27655e2b15d830f8bae5f0 (patch) | |
tree | ad4ad8a47de1eda9845f9f7b0baceeec907cf8d3 /src | |
parent | 15a9f57178a4ed4f01e8d8c69f3a72bf9c4fed7d (diff) | |
parent | ece18346582ffccb6d05b48b647ba5439aa2cca3 (diff) | |
download | scala-9e064f783e7ee42b9d27655e2b15d830f8bae5f0.tar.gz scala-9e064f783e7ee42b9d27655e2b15d830f8bae5f0.tar.bz2 scala-9e064f783e7ee42b9d27655e2b15d830f8bae5f0.zip |
Merge pull request #2688 from yllan/SI-7614
SI-7614 Minimize the times of evaluation f in TraversableOnce.maxBy/minBy
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/collection/GenTraversableOnce.scala | 26 | ||||
-rw-r--r-- | src/library/scala/collection/TraversableOnce.scala | 28 |
2 files changed, 52 insertions, 2 deletions
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index d966c7324b..3d1b2c4278 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -363,8 +363,34 @@ trait GenTraversableOnce[+A] extends Any { */ def max[A1 >: A](implicit ord: Ordering[A1]): A + /** Finds the first element which yields the largest value measured by function f. + * + * @param cmp An ordering to be used for comparing elements. + * @tparam B The result type of the function f. + * @param f The measuring function. + * @return the first element of this $coll with the largest value measured by function f + * with respect to the ordering `cmp`. + * + * @usecase def maxBy[B](f: A => B): A + * @inheritdoc + * + * @return the first element of this $coll with the largest value measured by function f. + */ def maxBy[B](f: A => B)(implicit cmp: Ordering[B]): A + /** Finds the first element which yields the smallest value measured by function f. + * + * @param cmp An ordering to be used for comparing elements. + * @tparam B The result type of the function f. + * @param f The measuring function. + * @return the first element of this $coll with the smallest value measured by function f + * with respect to the ordering `cmp`. + * + * @usecase def minBy[B](f: A => B): A + * @inheritdoc + * + * @return the first element of this $coll with the smallest value measured by function f. + */ def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A def forall(pred: A => Boolean): Boolean diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 526c36dda7..634807b29f 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -221,13 +221,37 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { if (isEmpty) throw new UnsupportedOperationException("empty.maxBy") - reduceLeft((x, y) => if (cmp.gteq(f(x), f(y))) x else y) + var maxF: B = null.asInstanceOf[B] + var maxElem: A = null.asInstanceOf[A] + var first = true + + for (elem <- self) { + val fx = f(elem) + if (first || cmp.gt(fx, maxF)) { + maxElem = elem + maxF = fx + first = false + } + } + maxElem } def minBy[B](f: A => B)(implicit cmp: Ordering[B]): A = { if (isEmpty) throw new UnsupportedOperationException("empty.minBy") - reduceLeft((x, y) => if (cmp.lteq(f(x), f(y))) x else y) + var minF: B = null.asInstanceOf[B] + var minElem: A = null.asInstanceOf[A] + var first = true + + for (elem <- self) { + val fx = f(elem) + if (first || cmp.lt(fx, minF)) { + minElem = elem + minF = fx + first = false + } + } + minElem } /** Copies all elements of this $coll to a buffer. |