Scalaのリストでのパターンマッチングについて少し混乱しています。
例えば。
val simplelist: List[Char] = List('a', 'b', 'c', 'd')
//> simplelist : List[Char] = List(a, b, c, d)
def simple_fun(list: List[Char]) = list match {
case (x:Char) :: (y:List[Char]) => println(x)
case _ => Nil
}
//> simple_fun: (list: List[Char])Any
simple_fun(simplelist)
//> a
//| res0: Any = ()
これは現在、1行の出力のみを出力します。リストの各要素で実行/パターン一致しないようにする必要がありますか?
編集:コンパイルエラーを修正し、REPLからの出力をコピーしました。
繰り返し呼び出す場合を除き、simple_fun
ある意味で、あなたが持っているものは最初の要素とパターンマッチし、それ以上は何もしません。リスト全体と一致させるには、simple_fun
は、次のように自分自身を再帰的に呼び出します。
val simplelist: List[Char] = List('a', 'b', 'c', 'd')
def simple_fun(list: List[Char]): List[Nothing] = list match {
case x :: xs => {
println(x)
simple_fun(xs)
}
case _ => Nil
}
Scalaコンパイラはそれらを推論できるので、一部のタイプを省略していることに注意してください。これにより、雑然としたコードが読みにくくなります。
ちょっとした付記として、関数内でprintln
を繰り返し呼び出すことは、特に副作用がないため、特に機能的ではありません。より慣用的なアプローチは、関数にリストを説明する文字列を作成させ、それをprintln
への1回の呼び出しで出力することです。これにより、副作用が1つの明確な場所に保持されます。このようなものは1つのアプローチです。
def simple_fun(list: List[Char]):String = list match {
case x :: xs => x.toString + simple_fun(xs)
case Nil => ""
}
println(simple_fun(simple_list))
また、リストのケースは、先頭と末尾だけでなく、N個のリスト要素だけでなく、分割することもできます。
def anyFunction(list: List[Int]): Unit =
list match {
// ...methods that have already been shown
case first :: second :: Nil => println(s"List has only 2 elements: $first and $second")
case first :: second :: tail => println(s"First: $first \nSecond: $second \nTail: $tail")
}
それが誰かに役立つことを願っています。
私は以下がうまくいくと思います:
def flatten(l: List[_]): List[Any] = l match {
case Nil => Nil
case (head: List[_]) :: tail => flatten(head) ::: flatten(tail)
case head :: tail => head :: flatten(tail)
}
最初の行はNilの一致なので、何も見つからない場合は何も返されません。 2行目はリストのリストを識別し、flattenメソッドを呼び出してリストのリストをフラット化します。