2016-01-23 101 views
0

我想通過模式匹配遞歸遍歷Scala中的列表。我不能使用任何列表函數,或者使用/ for循環。我需要做的是遍歷列表,並刪除一個元素,如果它匹配成'4'。我是新來的斯卡拉,我無法在教科書中找到答案,也沒有在Google上找到答案。其他人都使用過濾方法或其他列表方法。遞歸遍歷一個Scala列表

這裏就是我試圖做的(這是錯誤的)

def removeFours(lst: List[Int]): List[Int] = { 
val newLst = lst 
lst match { 
    case Nil => Nil 
    case a if a == 4 => newLst -= 0 
    case n => removeFours(newLst) 
} 
newLst 
} 

回答

6

看看這對你的作品。

def removeFours(lst: List[Int], acc: List[Int] = List.empty): List[Int] = { 
    lst match { 
    case Nil => acc.reverse 
    case 4 :: t => removeFours(t, acc) 
    case h :: t => removeFours(t, h :: acc) 
    } 
} 

用法:

scala> removeFours(List(3,7,4,9,2,4,1)) 
res84: List[Int] = List(3, 7, 9, 2, 1) 
2

使用一個內部函數和模式匹配脫結構列表。如果列表中的頭是4,則不要將其添加到累加器。如果是,請將其附加到累加器。

def removeFours(lst: List[Int]): List[Int] = { 
    def loop(lst: List[Int], acc: List[Int]): List[Int] = lst match { 
    case Nil => acc 
    case h :: t => 
     if (h == 4) { 
     loop(t, acc) 
     }else{ 
     loop(t, acc :+ h) 
     } 
    } 
    loop(lst, List()) 
} 

做到這一點的首選方法是使用模式匹配後衛,但如果else語句可能看起來比較熟悉,如果你是剛剛開始使用Scala。

def removeFours(lst: List[Int]): List[Int] = { 
    def loop(lst: List[Int], acc: List[Int]): List[Int] = lst match { 
    case Nil => acc 
    case h :: t if (h == 4) => loop(t, acc) 
    case h :: t => loop(t, acc :+ h) 
    } 
    loop(lst, List()) 
} 
+0

向'loop'函數添加'@ tailrec'註釋以確保它不會堆棧。它不會在這種情況下,但它總是一個很好的做法。 –