获取2D矢量(矩阵)中的元素

时间:2013-05-12 11:25:47

标签: scala

我正在搜索特定int的向量向量。

  def searchVectors(i: Int, vectors: Vector[Vector[Int]]) = {
    val x = vectors.indexWhere(_.indexWhere(_ == i))
    val y = vectors(x).indexOf(y)
    (x, y)
  }

你可以看到我得到y两次。首先是计算x时,然后再计算y时。 不好。我该怎么办,所以我只计算一次?

由于

4 个答案:

答案 0 :(得分:8)

您可以采取的一种方法是迭代所有向量:

def searchVectors(x: Int, vec: Vector[Vector[Int]]) =
  for {
    i <- 0 until vec.size
    j <- 0 until vec(i).size
    if vec(i)(j) == x
  } yield (i, j)

Vector也有zipWithIndex方法,它为集合的每个元素添加索引并创建它们的元组。所以你可以使用它来归档同样的东西:

def searchVectors(x: Int, vec: Vector[Vector[Int]]) =
  for {
    (subVec, i) <- vec.zipWithIndex
    (elem, j) <- subVec.zipWithIndex
    if elem == x
  } yield (i, j)

这种方法的优点是,您使用内部循环map / flatMap而不是外部(基于索引)循环。如果您将它与视图结合使用,则可以实现延迟搜索:

def searchVectors(x: Int, vec: Vector[Vector[Int]]) =
  for {
    (subVec, i) <- vec.view.zipWithIndex
    (elem, j) <- subVec.view.zipWithIndex
    if elem == x
  } yield (i, j)

不是你仍然会收到结果集合,但它是懒惰的集合。所以,如果你愿意这样做:

searchVectors(3, vector).headOption

它实际上会执行搜索(仅在此时),然后,当它找到时,它将作为Option返回。不会再进行搜索。

答案 1 :(得分:3)

这是一种更实用的方法:

def searchVectors(i: Int, vectors: Vector[Vector[Int]]) = {
  val outer = vectors.toStream map (_.indexOf(i))
  outer.zipWithIndex.filter(_._1 != -1).headOption map (_.swap)
}
编辑:我想我更喜欢这个:

def searchVectors(i: Int, vectors: Vector[Vector[Int]]) = {
  vectors.toStream.map(_.indexOf(i)).zipWithIndex.collectFirst {
    case (y, x) if y != -1 => (x, y)
  }
}

转换为Stream是可选的,但可能更有效,因为它可以避免在找到所需元素时搜索整个向量。

答案 2 :(得分:2)

这也困扰着我。您可能已经想到了这一点,但是如果您愿意违反不可变状态等功能的编程原理,则可以采用以下一种方法:

val v = Vector(Vector(1,2,3), Vector(4, 5, 6))
var c: Int = -1
val r = v.indexWhere(r => {c = r.indexOf(6); c != -1})
(r, c)

答案 3 :(得分:0)

这是一个易于理解的解决方案

foo