2013-05-15 42 views
0

所以這可能不是解決它的最好方法,但我最初的想法是表達式。 說我有喜歡查找2維斯卡拉列表中的字符

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。它似乎在抱怨說我的迭代器不匹配返回類型,但我不太明白爲什麼這是或怎麼處理它...

+0

見http://stackoverflow.com/a/8422714/770361 –

回答

1

findChar的簽名中,您告訴編譯器它返回(Int, Int)。但是,您的for表達式(由Scala推斷)的結果爲IndexedSeq[(Int, Int)],如錯誤消息所示。原因是yield之後(r, c)產生於for表達式中的每個「迭代」(即,您正在生成一系列結果,而不僅僅是一個結果)。

編輯:至於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) 
} 

其中aux是不實際的遞歸(並記住其子列表我們是一個(局部定義)的輔助功能,索引i)。在這個實現中,None的結果表明搜索到的元素不存在,而成功的結果可能返回類似Some((1, 1))的東西。

2

爲了您的另一隻耳朵,問題重複

How to capture inner matched value in indexWhere vector expression?

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))