如何在indexWhere向量表达式中捕获内部匹配值?

Dan*_*Dan 5 scala vector

使用Vector [Vector [Int]]引用v和表达式来查找给定的数字num:

val posX = v.indexWhere(_.indexOf(num) > -1)
Run Code Online (Sandbox Code Playgroud)

有没有办法捕获_.indexOf(num)的值在表达式后使用(即posY值)?以下表示错误"非法启动简单表达式":

val posX = v.indexWhere((val posY = _.indexOf(num)) > -1)
Run Code Online (Sandbox Code Playgroud)

小智 7

如果我们不介意使用变量,那么我们可以在var中捕获indexOf()内部Vector的值(_在下面的代码中)并稍后使用它来构建y位置:

val posX = v.indexWhere(_.indexOf(num) > -1)
val posY = v(posX).indexOf(num)
Run Code Online (Sandbox Code Playgroud)


Tra*_*own 6

有很多很好的功能方法可以做到这一点.以下可能是更简洁的一个:

val v = Vector(Vector(1, 2, 3), Vector(4, 5, 6), Vector(7, 8, 9))
val num = 4

val Some((posY, posX)) = v.map(_ indexOf num).zipWithIndex.find(_._1 > -1)
// posY: Int = 0
// posX: Int = 1
Run Code Online (Sandbox Code Playgroud)

请注意,这里还有很多额外的工作,但是我们正在创建一些中间集合,其中一部分是我们不需要的,等等.如果你正在调用这个东西或者非常大的集合,不幸的是,你可能需要采取更加迫切的方法.在那种情况下,我建议捆绑所有不愉快:

def locationOf(v: Vector[Vector[Int]])(num: Int): Option[(Int, Int)] = {
  var i, j = 0
  var found = false

  while (i < v.size && !found) {
    j = 0

    while (j < v(i).size && !found)
      if (v(i)(j) == num) found = true else j += 1

    if (!found) i += 1
  }

  if (!found) None else Some(i, j)
}
Run Code Online (Sandbox Code Playgroud)

虽然不那么优雅,但这种方法可能会更快,内存效率更高.它足够小,不太可能包含这种编程所容易出现的任何错误,而且它的引用是透明的 - 所有突变都是本地的.