0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ninety-Nine Scala Problems奮闘記6

Posted at

【リベンジ】P07 Flatten a nested list structure.

前回どうしても解けなかったP07にリベンジした。今回は「ネストしたList構造を一つのListにまとめる」のを

  1. 再帰
  2. flatmap

どちらでも実装するのが目標。

1. 再帰のパターン

結局自力では分からなかった。

自力でなんとか書いたコード

myAnswer
    def flatten (result: List[Any], ls: List[Any]): List[Any] = ls match {
      case ls::tail if ls == classOf[List[Any]] => {
        flatten(result, ls[Any])
        flatten(result, tail)
      }
      case h::tail => {
        flatten(result:+h, tail)
      }
      case Nil => result
      case _ => throw new NoSuchElementException
    }

そして当然のように動かない。

Error:(11, 27) value ls of type Any does not take type parameters.
        flatten(result, ls[Any])
                          ^

って言われる。

型パラメータの指定方法を学んだ後のコード

結局分からなかったので、S-99: Ninety-Nine Scala Problems所感 リスト操作編 - Soleil cou coupé を見てお勉強。

scala
  case (xs : List[_]) :: (ys : List[_]) => flatten(xs) ::: flatten(ys)

ああー…そんなことできるのか…。
前のエラーは、resultは型パラメータを取らないよって叱られてたから、受け取るresult自体をList[Any]に限定してやれば良かったみたいだ。

と思って直したが

myAnswer
    def flatten (result: List[Any], ls: List[Any]): List[Any] = ls match {
      case (ls:List[Any])::(tail:List[Any]) => {
        flatten(result, ls)
        flatten(result, tail)
      }
      case h::tail => {
        flatten(result:+h, tail)
      }
      case Nil => result
      case _ => throw new NoSuchElementException
    }

  //上記コードはmyAnswerのメソッド内メソッド
  println(myAnswer(List(List(1,1),2,List(3,List(5,8)))))

List(2)
Process finished with exit code 0

動かない。

普通にロジックがおかしかった

そういやresultの扱いがおかしいわ。
じゃあこうか。

myAnswer
    def flatten (result: List[Any], ls: List[Any]): List[Any] = ls match {
      case (ls:List[Any])::(tail:List[Any]) => {
        flatten(result, ls):::flatten(result, tail)
      }
      case h::tail => {
        flatten(result:+h, tail)
      }
      case Nil => result
      case _ => throw new NoSuchElementException
    }

List(1, 1, 2, 3, 5, 8, 2, 3, 2)
Process finished with exit code 0

うーん。だいぶ近くなっては来たけど…
パターンマッチがまだおかしい。

降参して回答例を見た。
Flatten a list - Rosetta Code

RosettaCode
def flatList(l: List[_]): List[Any] = l match {
  case Nil => Nil
  case (head: List[_]) :: tail => flatList(head) ::: flatList(tail)
  case head :: tail => head :: flatList(tail)
}

自分のものと違うのは、与えられたListが「ListとListの結合」という場合がないことと、結果を入れようと思って設定したresultがないこと。

美しい再帰を書く道のりは長い…。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?