对于这个确切的用例,您可以使用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")
}
如您所见,这不是很漂亮,但如果有更好的名字,它可能对您有用。
这里有一些解释:
结果如预期:
List(King, List(134, 151, 130), USA)
如 cmets 中所述,如果可以,您应该更改数据结构。
这样就容易多了。例如:
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