2013-05-08 52 views
1

我有一个二维集合(说Vector[Vector[Int]]),我想找到它中的一个元素的索引。我的解决方案是这样的:查找二维集合中的元素(不含var)

def find(vec: Vector[Vector[Int]], target: Int) = { 
    def indexOfTarget(v: Vector[Int]) = v.indexOf(target) 

    val r = vec.indexWhere((v) => indexOfTarget(v) != -1) 
    val c = indexOfTarget(vec(r)) 

    (r, c) 
} 

但它只是...丑陋。它会再次调用indexOfTarget一次。

有没有更好的方法?

回答

3

如何:

vec.view.zipWithIndex.map { 
    case (iv,i) => (i, iv.indexOf(target)) 
}.find(_._2 != -1) 

注意,感谢view,在zipWithIndexmap懒洋洋地评估,这因此也就只有是绝对必需的计算。

+0

我同意,但也许应该提到的是,'view.zipWithIndex'是懒洋洋地评估,所以这应该是 - 足够高效。此外,这里不需要额外的'val idxs',因为find可以直接附加到映射上,如:'veq.view.zipWithIndex.map {case(sub,idx)=>(idx,sub.indexOf(target ))} .find(_._ 2!= -1)'。 也可以使用'Seq'而不是'Vector'。 – 2013-05-08 06:03:27

+0

@michael_s感谢您的评论。据此编辑。 – gzm0 2013-05-08 15:30:03

0

你可以试试这个:

def find(vec: Vector[Vector[Int]], target: Int) = { 
    val zipped = vec.zipWithIndex 
    val result = for{ 
    tup <- zipped 
    index <- List(tup._1.indexOf(target)) 
    if (index != -1) 
    } yield (tup._2, index) 
    result.headOption 
} 

结果类型将是同在一处None如果没有匹配的Option[(Int,Int)]

0

返回Some((x, y))如果元素存在的实现,否则None

def find(vec: Vector[Vector[Int]], target: Int) = (for { 
    (xs, posX) <- vec.view.zipWithIndex 
    (`target`, posY) <- xs.view.zipWithIndex 
} yield (posX, posY)).headOption 


scala> find(Vector(Vector(1, 2, 4), Vector(2, 2, 3)), 3) 
res0: Option[(Int, Int)] = Some((1,2))