我有一个像:
这样的数组val a = Array(0, 6, 15, 0, 20, 0)
如果我使用reduceLeft
函数来查找此数组中的最小值,例如:
val f = (x: Int, y: Int) => x min y
val rlf = a.reduceLeft(f)
我怎么能找到这个数组中最小的数字,不包括与0
的比较,因为在我的情况下我使用0
作为默认值而不是我要比较的东西?!
答案 0 :(得分:12)
<强>产地:强>
scala> val a = Array(0, 6, 15, 0, 20, 0)
a: Array[Int] = Array(0, 6, 15, 0, 20, 0)
scala> a.filterNot(_==0).min
res6: Int = 6
<强>更新强> 过滤后我错过了空数组的情况。所以正确的版本就像
a.filterNot(_==0) match {
case Array() => -1
case arr => arr.min
}
或
Try(a.filterNot(_==0).min).getOrElse(-1)
<强>更新强> 使用索引得到min:
Try(a.zipWithIndex.filterNot(_._1 == 0).minBy(_._1)).getOrElse((-1,-1))
或者
a.zipWithIndex.filterNot(_._1==0) match {
case Array() => (-1,-1)
case arr => arr.minBy(_._1)
}
或(@Ryan解决方案,对阵列进行一次迭代)
a.foldLeft((-1, -1, 0)) {
case ((min, minInd, length), n) =>
if (n == 0) (min, minInd, length + 1)
else if (min > -1) {
val localMin = Math.min(min, n)
(localMin, if (localMin == min) minInd else length, length + 1)
}
else (n, length, length + 1)
}
使用&#34; classic&#34;它可能更漂亮。循环优化解决方案。
答案 1 :(得分:3)
您可以使用foldLeft
一次性完成此操作,这也将处理空案例:
a.foldLeft(-1) { (min, n) =>
if (n == 0)
min
else if (min > -1)
Math.min(min, n)
else
n
}
以-1开头。如果n
为0,请使用先前的最小值。如果先前的最小值大于-1,则取前一个最小值的最小值n
。否则(这只是第一个非零n
),n
是新的最小值。
foldLeft
可以安全地用于空集合,因为您提供了默认值。如果你有一个空数组,foldLeft
在这种情况下只返回-1。