2017-05-15 83 views
1

我正在嘗試使用模式匹配在scala中查找列表的最後一個元素。我想下面的代碼模式匹配找到列表的最後一個元素

def last[A](list: List[A]):A = list match { 
case head :: Nil => head 
case head :: tail => last(tail) 
case _ => Nil 
} 

最後一種情況,即案件_ =>無拋出錯誤類型不匹配(發現Nil.type要求A)

我知道這個問題可以用其他方法,但是使用來解決只有模式匹配纔有辦法解決這個問題?

由於列表是泛型類型,所以我不能用N的缺省值替換,只能在運行時確定類型A的缺省值。

刪除該行:case _ =>無顯然正在工作,但有一個警告,它會在無參數的情況下失敗。

那麼,在這種情況下如何處理無參數?

回答

2

使用Option[T]返回結果,所以如果有一些元件迴流Some(lastElement)否則Option.empty

例,

def last[A](list: List[A]): Option[A] = list match { 
    case head :: Nil => Option(head) 
    case head :: tail => last(tail) 
    case _ => Option.empty 
    } 

    it("returns last element") { 

    assert(last(List("apple")) == Some("apple")) 
    assert(last(List("apple", "mango")) == Some("mango")) 
    assert(last(List()) == Option.empty) 
    assert(last(List()) == None) 

    } 

如何訪問Option[T]

last(List("In absentia", "deadwind")) match { 
    case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}") //prints Yayy there was lastValue = deadwind 
    case None => println("Oops list was empty") 
} 

last(List()) match { 
    case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}") 
    case None => println("Oops list was empty") //prints Oops list was empty 
} 

// or using map 
last(List("In absentia", "deadwind")).map(lastValue => print(s"lastValue is ${lastValue}")) 
+0

有什麼辦法可以在這裏指定類似於「Null」的東西(比如在Java中)泛型類型(這樣我們可以避免使用Option)? – Shashank

+0

不推薦,因爲這個想法是刪除'null'的概念。最後一個元素可以是「某個值」或「空」。你有任何問題操縱返回的'Option'值? 'returnsValue match {}'是處理返回的最後一個值的方法 – prayagupd

+2

Shashank,在罕見的情況下,你可能會看到這樣的情況,它在性能上有很大的差異,但它不會是慣用的Scala。請注意,在這種情況下,您必須將A限制爲AnyRef,即'last [A <:AnyRef]'。 – AmigoNico

2

由於您不確定您的列表是否包含任何對象,因此您應該以一般方式處理這種情況。我建議你last方法返回選項類型如下:

def last[A](list: List[A]): Option[A] = list match { 
    case head :: Nil => Some(head) 
    case head :: tail => last(tail) 
    case _ => None 
} 

然後在你的代碼,你可以使用單子一樣的界面,結果工作。您可以使用map並在提供的功能中處理數據,也可以在選項中使用get方法,以防絕對確定列表不爲空。

8

您可以模式匹配:+

def last[A](list: List[A]) = list match { 
    case init :+ last => Some(last) 
    case _ => None 
} 
+0

不錯。當然,也是尾遞歸的。恕我直言,這應該成爲正確的答案。 – AmigoNico

相關問題