2016-03-31 16 views
3

ループを使用して複数のリストを連結する方法を知りたいと思います。ここで私は何をしようとしているの例です:複数のリストを連結する

object MyObj { 
    var objs = Set (
    MyObj("MyObj1", anotherObjList), 
    MyObj("MyObj2", anotherObjList) 
) 

    val list = List.empty[AnotherObj] 
    def findAll = for (obj <- objs) List.concat(list, obj.anotherObjList) 
} 

私はセットOBJSのオブジェクトからリストを連結するには、関数のfindAllをしたいと思います。

答えて

5

はこれを試してみてください:

objs.flatMap(_.anotherObjList) 

それはforを使用していないが、それはおそらく、Scalaでそれを行うための最も簡潔で読みやすい方法です。

1

使用reduce

このような何か:

objs.reduce((a,b) => a.anotherObjList ++ b.anotherObjList) 

それともSetが空にすることができれば、foldLeftを使用します。

objs.foldLeft(List.empty[AnotherObj],(a,b) => a.anotherObjList ++ b.anotherObjList) 
+0

これはコンパイルされません。 'a'は' MyObj'ではなく 'List'です –

+0

' a'がなぜリストになるのですか? 'objs'は' MyObjs'の 'Set'です。 –

+0

私は減らす方法を試していましたが、うまく機能しませんでした。エラーは型の不一致です。 found:List [AnotherObj]、MyObjが必要です – jerome

1

あなたのコード例では、vallistを使用しています再割り当てすることはできません。あなたがList.concat(list, obj.anotherObjList)を行うと、あなたは現在のobjanotherObjListに空listをconcats新しいリストを作成しているが、結果が使用されることはありませんので、listはまだforループの実行後に空になります。

object MyObj { 
    var objs = Set(
    MyObj("MyObj1", anotherObjList), 
    MyObj("MyObj1", anotherObjList), 
) 

    def findAllLoop1 = { 
    var list = List.empty 
    for (obj <- objs) list = list ++ obj.anotherObjList 
    list 
    } 

    def findAllLoop2 = { 
    val buf = collection.mutable.ListBuffer[Int]() // replace Int with your actual type of elements 
    for (obj <- objs) buf ++= obj.anotherObjList 
    } 
} 

あなたが本当にforループ不可欠を使用し、いずれかの不変なコレクションを使用して、forループの体から再割り当てすることができvarに割り当てるか、変更可能なコレクションを使用する必要がある場合

しかし、何らかの理由で強制的なループを使用する必要がない場合は、機能的な代替手段を使用することを強くお勧めします。

object MyObj { 
    var objs = Set(
    MyObj("MyObj1", anotherObjList), 
    MyObj("MyObj1", anotherObjList), 
) 

    def findAll = 
    objs.flatMap(_.anotherObjList) // if Set as return type is okay 

    def findAll: List[Int] = 
    objs.flatMap(_.anotherObjList)(collection.breakOut) // if elements are of type Int and you want to get a List at the end, not a Set 
} 
関連する問題