0

所以这可能不是解决它的最佳方法,但我最初的想法是表达。说我有一个类似的列表

List(List('a','b','c'),List('d','e','f'),List('h','i','j'))

我想找到一个字符的行和列,比如说'e'

def findChar(letter: Char, list: List[List[Char]]): (Int, Int) =
  for {
    r <- (0 until list.length)
    c <- (0 until list(r).length)
    if list(r)(c) == letter
  } yield (r, c)

如果有更优雅的方式,我会全神贯注,但我也想了解这有什么问题。具体来说,编译器在这里给我的错误是

type mismatch;  found   : scala.collection.immutable.IndexedSeq[(Int, Int)]  required: (Int, Int)

在分配给 的行上r。似乎在抱怨我的迭代器与返回类型不匹配,但我不太明白为什么会这样或该怎么做......

4

2 回答 2

2

findChar您的签名中告诉编译器它返回(Int, Int)。但是,您的for表达式的结果(由 Scala 推断)IndexedSeq[(Int, Int)]如错误消息所示。原因是表达式中的每个“迭代”都会生成(r, c)after (即,您正在生成一系列结果,而不仅仅是单个结果)。yieldfor

编辑:至于findChar,你可以这样做:

def findChar(letter: Char, list: List[List[Char]]) = {
  val r = list.indexWhere(_ contains letter)
  val c = list(r).indexOf(letter)
  (r, c)
}

它不是最有效的解决方案,但相对较短。

编辑:或重用你原来的想法:

def findAll(letter: Char, list: List[List[Char]]) =
  for {
    r <- 0 until list.length
    c <- 0 until list(r).length
    if list(r)(c) == letter
 } yield (r, c)

def findChar(c: Char, xs: List[List[Char]]) = findAll(c, xs).head

在这两种情况下,请注意如果搜索的字母不包含在输入列表中,则会发生异常。

编辑:或者你自己写一个递归函数,比如:

def findPos[A](c: A, list: List[List[A]]) = {
  def aux(i: Int, xss: List[List[A]]) : Option[(Int, Int)] = xss match {
    case Nil => None
    case xs :: xss =>
      val j = xs indexOf c
      if (j < 0) aux(i + 1, xss)
      else Some((i, j))
  }
  aux(0, list)
}

whereaux是一个(本地定义的)辅助函数,它执行实际的递归(并记住我们在哪个子列表中,索引i)。在这个实现中,结果None表明搜索到的元素不存在,而成功的结果可能会返回类似Some((1, 1)).

于 2013-05-15T04:30:02.020 回答
2

对于你的另一只耳朵,问题重复了

如何在 indexWhere 向量表达式中捕获内部匹配值?

scala> List(List('a','b','c'),List('d','e','f'),List('h','i','j'))
res0: List[List[Char]] = List(List(a, b, c), List(d, e, f), List(h, i, j))

scala> .map(_ indexOf 'e').zipWithIndex.find(_._1 > -1)
res1: Option[(Int, Int)] = Some((1,1))
于 2013-05-15T06:37:24.013 回答