如何捕获索引中的内部匹配值向量表达式?

问题描述:

使用矢量[向量[INT]]参考v以及表达找到给定数量NUM:如何捕获索引中的内部匹配值向量表达式?

val posX = v.indexWhere(_.indexOf(num) > -1) 

是否有任何的方式来捕捉_.indexOf(NUM)的值后的使用表达式(即posY值)?下面的信号错误“简单表达非法的开始”:

val posX = v.indexWhere((val posY = _.indexOf(num)) > -1) 
+2

你好,来自Scala的函数式编程课程! :) – 2014-10-29 05:01:28

有很多不错的功能的方式来做到这一点。以下是可能的更简洁之一:

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 

注意,有很多额外的工作会在这里,但是 - 我们创造了几个中间集合,其中有一部分,我们并不需要,等等。如果你很多或者非常大的集合中调用了这个东西,那么不幸的是你可能需要采取一个更为强制性的方法。在这种情况下,我建议捆绑了所有的不愉快:

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) 
} 

不优雅,但这种方法很可能将是一个很大更快,更高效的内存。它足够小,它不可能包含任何这种编程很容易出现的错误,并且它是引用透明的 - 所有的突变都是局部的。

从我的扶手椅,

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

scala> v.zipWithIndex collectFirst { 
    | case (e, i) if (e indexOf num) >= 0 => 
    | (i, e indexOf num) 
    | } 
res7: Option[(Int, Int)] = Some((1,0)) 

我没有做过的扶手椅数学,但相比特拉维斯的这一个中间集合。但请参阅特拉维斯的评论,即结果内部指数在这里计算两次,整个过程并非如此。

+1

您可以在'.zipWithIndex'之前添加'.view'来获得0个中间集合。 – senia 2013-05-12 04:47:17

+2

请注意,这通过搜索每个内部向量两次来保存中间集合('e indexOf num')。 – 2013-05-12 10:25:32

如果我们不介意使用一个变量,然后我们可以在一个VAR捕捉内向量的indexOf()值(_在下面的代码),后来用它来构建y位置:

val posX = v.indexWhere(_.indexOf(num) > -1) 
val posY = v(posX).indexOf(num) 

这里这个解决方案只会在找到需要的元素之前进行评估。我个人认为它更具可读性,您可以在各种程序中重复使用它。如果需要的话,你显然可以做得更一般。

val v = Vector(Vector(1, 2, 3), Vector(4, 5, 6)) 

def findElem(i: Int, vs: Vector[Vector[Int]]): (Int, Int) = 
    (for { 
     row <- vs.indices.toStream 
     col <- vs(row).indices.toStream 
     if vs(row)(col) == i 
    } yield (row, col)).head 

findElem(5, v) // (1, 1) 

,如果你想所有的位置,您可以删除.toStream方法。使用.toStream仅意味着您只会评估到第一次出现为止。