找到除0以外的数组中的最小值

时间:2015-07-24 13:24:38

标签: arrays scala vector

我有一个像:

这样的数组
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作为默认值而不是我要比较的东西?!

2 个答案:

答案 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。