Для этого конкретного варианта использования вы можете использовать Pattern Matching
:
val doubleList = List(List("King",List("134"),"USA"), List("King",List("151","130"),"USA"))
doubleList match {
case (a :: (b:List[_]) :: c :: _) :: (_ :: (d:List[_]) :: _) :: _ => a :: (b ++ d) :: c :: Nil
case other => println(s"Not expected: $other")
}
Как вы можете видеть, это не так красиво, но с лучшими именами это может работать для вас.
Вот некоторые объяснения:
a::b::c
представляет список, где a и b - первые два элемента, а c - остаток (хвост)
_
- это значения, которые вас не интересуют, в нашем случае хвосты и тип списка.
, остальные составляют ваши списки, и результат объединяет оба подсписка.
Результат, как и ожидалось:
List(King, List(134, 151, 130), USA)
Как указано в комментариях, вы должны изменить структуру данных, если можете.
Тогда это было бы проще. Например:
case class MyObj(name: String, indices: List[String], country: String) {
def merge(other: MyObj): MyObj =
copy(indices = indices ++ other.indices)
}
val obj1 = MyObj("King",List("134"),"USA")
obj1.merge(MyObj("King",List("151","130"),"USA"))
Это лучше читать.
Обновление : Решение для комментария:
Вы можете использовать groupBy
а затем с помощью flatMap
объединить внутренние списки:
st.groupBy(e => (e._1, e._3)) // -> Map((COOK,ENG) -> List((COOK,List(100),ENG), ...)
.map{ case ((n, c), list) => (n, list.flatMap(_._2), c)}
.toList
.sortBy(_._1)
Возвращается, как и ожидалось: List((COOK,List(100, 125, 135, 145),ENG), (KIM,List(115, 134, 148, 154),AUS), (TIM,List(102, 105),ZIM), (VIR,List(115, 120, 134),IND))
_._1
- это способ доступа к записям кортежа.
Обновление 2 : Продолжить сортировку
Это возможно, но AFAIK становится сложным. Я не уверен, что это достаточно читабельно:
st
.zipWithIndex // add an index for later sorting
.groupBy { case (e, _) => (e._1, e._3) }
.map { case ((n, c), groupedList) => (n,
groupedList.map { case (trible, index) => (trible._2, index) } // you are only interested in the list and the index
.foldLeft((List.empty[String], Int.MaxValue)) { case ((list1, i1), (list2, i2)) =>
(list1 ++ list2, Math.min(i1, i2)) // fold over all the lists and take the minimal index
}
, c)
}.toList
.sortBy { case (_, (_, index), _) => index } // sort the result by the index
.map { case (n, (list, _), c) => (n, list, c) } // get rid of the index