2012-10-24 9 views
11

Listをフラット化する関数を記述したいと思います。Scala flatten List

object Flat { 
    def flatten[T](list: List[T]): List[T] = list match { 
    case Nil => Nil 
    case head :: Nil => List(head) 
    case head :: tail => (head match { 
     case l: List[T] => flatten(l) 
     case i => List(i) 
    }) ::: flatten(tail) 
    } 
} 

object Main { 
    def main(args: Array[String]) = { 
    println(Flat.flatten(List(List(1, 1), 2, List(3, List(5, 8))))) 
    } 
} 

私はそれが動作しない理由はわからないが、それはList(1, 1, 2, List(3, List(5, 8)))を返しますが、それはList(1, 1, 2, 3, 5, 8)をする必要があります。

私にヒントを教えてもらえますか?削除線で

+0

これは演習として楽しいです。実際のコードではもちろん、 'List'に' flatten'メソッドがあります。 – AshleyF

+0

この場合、それは動作しません。ここのリストは 'List [Any]'ですので、Any => TraversableOnce [_]から暗黙の変換を定義してflattenを呼び出さなければなりません。それは可能でなければならないが、私はそれがこの機能より簡単だとは思わない。 – rjsvaljean

+0

コンパイラのエラーと警告を見てください:彼らはいくつかの大きな手がかりを与えます –

答えて

9
case head :: Nil => List(head) 

あなたは正しい答えを得るでしょう。

は、リストの最後の要素は、あなたが巣にあなたのmatch文を必要としない

26

を処理されませんライン4で

List(List(List(1))) 

テストケースを考えてみて。代わりに、次のようにマッチングを行います。

def flatten(xs: List[Any]): List[Any] = xs match { 
    case Nil => Nil 
    case (head: List[_]) :: tail => flatten(head) ++ flatten(tail) 
    case head :: tail => head :: flatten(tail) 
    } 
+0

非常にエレガントなソリューション、共有ありがとう! – Ashalynd

15

私は、SDJMcHattie'sのソリューションに相当します。

def flatten(xs: List[Any]): List[Any] = xs match { 
    case List() => List() 
    case (y :: ys) :: yss => flatten(y :: ys) ::: flatten(yss) 
    case y :: ys => y :: flatten(ys) 
    } 
+3

私の意見で最もエレガントな解決策 – Vic

+0

'(x :: ys)::: yss'は'それが要素のリストであり、別のリストの後にあれば 'どういう意味でしょうか? ( '() 'はAFAIKではないタプルを意味します) –

1
def flatten(ls: List[Any]): List[Any] = ls flatMap { 
    case ms: List[_] => flatten(ms) 
    case e => List(e) 
    }