2016-03-31 2 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) 
} 

Я хотел бы функцию FindAll конкатенировать списки от объекта заданных OBJS.

ответ

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' является' List', а не 'MyObj' –

+0

Почему' '' был List? 'objs' - это' Set' 'MyObjs'. –

+0

Я пробовал уменьшить путь, он не работал. Ошибка - несоответствие типа; найдено: List [AnotherObj], требуется MyObj – jerome

1

В вашем примере кода вы используете vallist который не может быть переназначен. Когда вы делаете List.concat(list, obj.anotherObjList) вы создаете новый список, который concats пустой list на текущий obj «s anotherObjList, но результат никогда не используется, так list все равно будет пустым после выполнения для-цикла.

Если вам действительно нужно использовать императив для цикла, либо использовать неизменяемое собрание и назначить его на var, который можно переназначить из тела для цикла или использовать изменяемые коллекции:

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 
    } 
} 

Но если по какой-то причине вам не нужно использовать императивный цикл, я бы настоятельно рекомендовал использовать функциональную альтернативу:

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 
} 
Смежные вопросы