2017-12-31 42 views
0

私はScalaを初めて使いました。コレクションのパターンマッチングについて学び、最後の要素を見つけるために単純なロジックを一般的に書きました。ここに私の最初の試みがあります:Scalaリストの最後から2番目の要素を探す

@scala.concurrent.tailrec 
def penultimate[A](elems: List[A]) = elems match { 
    case Nil => None 
    case first :: second :: Nil => Some(first) 
    case head :: tail => penultimate(tail) 
} 

これは十分ですか?私は尾の再帰について読んで、私のメソッドを尾の再帰的なものにしました!

しかし、それは次のような場合のために失敗し、私が期待するところ一部は(1):

penultimate[Int](List(1)) // This should give me Some(1) 

は私が行うことができることをより良いものはありますか? Scalaコレクションライブラリのreverseメソッドを使用してこれを1つのライナーにすることはできますが、私はそれを使用しないようにしたいと考えていました。

良いアプローチがありますか?

+0

あなたの言うことは間違っています。まず、あなたのコードはコンパイルされません。 2番目:コンパイルエラーを修正すると、 ''最後から2番目(List(1)) 'は' None'を返します。 –

+0

混乱して申し訳ありません!私は自分の投稿を編集しました! –

+0

今私は混乱しています。どうしてあなたは何かを信じるだろうか? –

答えて

1

これらの2つの単純なコンパイルエラーを修正すると、コードが正しく動作しているようです。この方法を書き込む別の方法である:

def penultimate[A](elems: List[A]) = elems match { 
    case _ :+ elem :+ _ => Some(elem) 
    case elem +: Nil => Some(elem) // strange extra requirement 
    case _ => None 
} 

:+は、(1)すべてのリストが、最後の要素、及び(2)最後の要素にSeqを解体します。 ::またはより一般的な+:のように、しかし後方に。私はcase init :+ elem :+ lastと書くことができましたが、私は使用したくないパターンの部分に名前を付けることを好まないのです。

+0

最初の大文字が最後から2番目の要素とどのようにマッチするかについて私はいくつかの説明をしてくれますか? –

+0

私はいくつかの説明を追加しました。 –

関連する問題