我想使用for comprehension找到数组的min和max元素.是否可以通过一次迭代的数组来找到min元素和max元素?
我正在寻找一个解决方案,而不使用scala提供的array.min或max.
这是一个简洁易读的解决方案,可以避免丑陋的if
陈述:
def minMax(a: Array[Int]) : (Int, Int) = { if (a.isEmpty) throw new java.lang.UnsupportedOperationException("array is empty") a.foldLeft((a(0), a(0))) { case ((min, max), e) => (math.min(min, e), math.max(max, e))} }
Explanation:foldLeft
Scala中许多集合的标准方法.它允许将累加器传递给将为数组的每个元素调用的回调函数.
请查看scaladoc以获取更多详细信息
遵循其他答案-可能有一个更通用的解决方案,该解决方案适用于其他集合Array
,和其他内容以及Int
:
def minmax[B >: A, A](xs: Iterable[A])(implicit cmp: Ordering[B]): (A, A) = { if (xs.isEmpty) throw new UnsupportedOperationException("empty.minmax") val initial = (xs.head, xs.head) xs.foldLeft(initial) { case ((min, max), x) => (if (cmp.lt(x, min)) x else min, if (cmp.gt(x, max)) x else max) } }
例如:
minmax(List(4, 3, 1, 2, 5)) //> res0: (Int, Int) = (1,5) minmax(Vector('Z', 'K', 'B', 'A')) //> res1: (Char, Char) = (A,Z) minmax(Array(3.0, 2.0, 1.0)) //> res2: (Double, Double) = (1.0,3.0)
(也可以使用cmp.min()
和来更简洁地编写此代码cmp.max()
,但前提是要删除B >: A
类型绑定,这会使函数的通用性降低)。
val xs: Array[Int] = ??? var min: Int = Int.MaxValue var max: Int = Int.MinValue for (x <- xs) { if (x < min) min = x if (x > max) max = x }
def findMinAndMax(array: Array[Int]) = { // a non-empty array val initial = (array.head, array.head) // a tuple representing min-max // foldLeft takes an initial value of type of result, in this case a tuple // foldLeft also takes a function of 2 parameters. // the 'left' parameter is an accumulator (foldLeft -> accum is left) // the other parameter is a value from the collection. // the function2 should return a value which replaces accumulator (in next iteration) // when the next value from collection will be picked. // so on till all values are iterated, in the end accum is returned. array.foldLeft(initial) { ((min, max), x) => if (x < min) (x, max) else if (x > max) (min, x) else acc } }
考虑一下(对于非空的可订购数组),
val ys = xs.sorted val (min,max) = (ys.head, ys.last)
您可以使用reduceLeft
函数获取Array [Int]的最小值和最大值.
scala> val a = Array(20, 12, 6, 15, 2, 9)
a:Array [Int] = Array(20,12,6,15,2,9)
scala> a.reduceLeft(_ min _)
res:Int = 2
scala> a.reduceLeft(_ max _)
res:Int = 20
有关更多信息和reduceLeft
方法示例,请参阅此链接:http://alvinalexander.com/scala/scala-reduceleft-examples