微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从Scala中的向量向量获取元素的索引?

如何解决如何从Scala中的向量向量获取元素的索引?

我有这个数据结构编码平面中元素的存在/不存在:

val rows = Vector(
  Vector("-","-","-"),Vector("-","X","-"))

我想得到一对“X”的坐标。假设左上角(0,0)

我试图通过这样的理解来获得结果:

for
  row <- rows
  rowIndex <- 0 until rows.length
  colIndex = row.indexOf("X")
  if (colIndex > -1)
yield (rowIndex,colIndex)

这正确地找到了 colIndex,但我需要以某种方式将 rowIndex 绑定到特定的 row。现在,它使用元素独立地迭代 row,rows.length 次。

第二个问题: 如果有多个元素,我们正在寻找,如何让它在找到第一个后停止搜索?结果应该只是一对(row,col)

解决方法

利用向量可以通过索引快速访问的优势,您可以这样做:

def firstIndexWhere[A](data: Vector[Vector[A]])(cond: A => Boolean): Option[(Int,Int)] =
  Iterator.range(start = 0,end = data.length).flatMap { i =>
    Iterator.range(start = 0,end = data(i).length).map { j =>
      (i,j)
    }
  } find {
    case (i,j) =>
      cond(data(i)(j))
  }

这将在第一个成功的索引处有效地停止。

另一种方法可能是:

def firstIndexWhere[A](data: Vector[Vector[A]])(cond: A => Boolean): Option[(Int,Int)] =
  data.iterator.zipWithIndex.map {
    case (row,i) =>
      row.iterator.zipWithIndex.collecFirst {
        case (elem,j) if (cond(elem)) => (i,j)
      }
  } collectFirst {
    case Some(indexes) => indexes
  }
,

一种选择是纯粹的递归方法:

def findIndex2D[T](v: Vector[Vector[T]],value: T): Option[(Int,Int)] = {
  val outSize = v.size
  val inSize = v.headOption.fold(0)(_.size)

  def loop(outer: Int,inner: Int): Option[(Int,Int)] =
    if (outer >= outSize) {
      None
    } else if (inner >= inSize) {
      loop(outer + 1,0)
    } else if (rows(outer)(inner) == value) {
      Some((outer,inner))
    } else {
      loop(outer,inner + 1)
    }

  loop(0,0)
}

或者可能是混合体:

def findIndex2D[T](v: Vector[Vector[T]],Int)] = {
  def loop(outer: Int): Option[(Int,Int)] =
    if (outer >= v.size) {
      None
    } else {
      val inner = rows(outer).indexOf(value)
      if (inner >= 0) {
        Some((outer,inner))
      } else {
        loop(outer + 1)
      }
    }

  loop(0)
}

我会让读者决定这些是否比仅使用内置函数的解决方案更好。它们是更复杂搜索的良好起点(例如查找第 n 个匹配值)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。