获取2D矢量(矩阵)中的元素
问题描述:
我正在为特定的int搜索矢量矢量。获取2D矢量(矩阵)中的元素
def searchVectors(i: Int, vectors: Vector[Vector[Int]]) = {
val x = vectors.indexWhere(_.indexWhere(_ == i))
val y = vectors(x).indexOf(y)
(x, y)
}
你可以看到我得到了两次。首先计算x,然后再计算y。 不好。我该怎么做,所以我只计算一次?
感谢
答
你可以采取的一个办法是只遍历所有向量:
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)
矢量也有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
。将不会执行进一步的搜索。
答
这里是一个更实用的方法来做到这一点:
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
是可选的,但可能更有效,因为它避免了搜索整个矢量,如果已经找到了所需的元素。
顺便说一句,我会命名项目查找为'x'或'z'或以某种方式除了'i'(i,j,k是索引) – 2013-05-12 11:28:32
也你的代码不能编译 – soulcheck 2013-05-12 11:31:32