List 如何合并列表';元素,其中每个列表元素都有三个元组?

List 如何合并列表';元素,其中每个列表元素都有三个元组?,list,scala,merge,tuples,List,Scala,Merge,Tuples,我有这个: List(List("King",List("134"),"USA"),List("King",List("151","130"),"USA")) 我终于想要这个了: List("King",List("134","151","130"),"USA") 对于这个确切的用例,您可以使用模式匹配: val doubleList = List(List("King",List("134"),"USA"), List("King",List("151","130"),"USA")) d

我有这个:

List(List("King",List("134"),"USA"),List("King",List("151","130"),"USA"))
我终于想要这个了:

List("King",List("134","151","130"),"USA") 

对于这个确切的用例,您可以使用
模式匹配

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(100125135145),ENG),(KIM,List(115134148154),AUS),(TIM,List(102105),ZIM),(VIR,List(115120134),IND))

。\u 1
是访问元组项的方式

更新2:继续排序

这是可能的,但可能会变得复杂。我不确定这是否足够可读:

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

你试过什么?你能分享你的一些努力吗(代码)?
List(“国王”,List(“151”,“130”),“美国”)
这太可怕了。不要这样做。Scala将把它转换为最接近的共同祖先,
Any
,在这种情况下,您实际上无法使用它做任何事情。您需要提供更多示例。例如,不清楚如果一个内部列表的头是“国王”,尾是“澳大利亚”,会发生什么情况。我想如果两个元素的头(国王)和尾(美国),它们的主体即列表应该合并。既然你在问题标题中说了三个元组,但实际上在主体中使用了
list
,你能澄清一下吗?如果列表包含两个以上的元素,如列表((“VIR”,list(“115”),“IND”),(“KIM”,list(“115”),“AUS”),(“COOK”,list(“100”),“ENG”),(“VIR”,list(“120”,“134”),“IND”),(“KIM”,list(“134”,“148”,“154”),“AUS”),(“COOK”,“list”(“125”,“135”,“145”),“ENG”),“ENG”),“TIM”,“list”(“102”),该怎么做我希望根据第一个和第三个元组合并第二个元组,并且列表的顺序不应该像上面的列表那样打破最终列表:列表((“VIR”,list(“115”,“120”,“134”),“IND”),(“KIM”,list(“115”,“134”,“148”,“154”),“AUS”),(“COOK”,list(“100”,“125”,“135”,“145”),“ENG”),(“TIM”,list(“102”,“105”),“ZIM”))谢谢!!还有一件事,通过这种方法,我按照第一个元素的字母顺序得到最终列表,但我希望顺序与前面的列表相同,就像我的列表是:::列表((“VIR”,list(“115”),“IND”),(“KIM”,list(“115”),“AUS”),(“COOK”,list(“100”),“ENG”),(“VIR”,list(“120”,“134”),“IND”),(“KIM”,list(“134”,“148”,“154”),“AUS”),“COOK”,list(“125”,“135”),最后,这个列表应该是:::list((“VIR”,list(“115”,“120”,“134”),“IND”),(“KIM”,list(“115”,“134”,“148”,“154”),“AUS”),(“COOK”,list(“100”,“125”,“135”,“145”),“ENG”),(“TIM”,list(“102”,“105”),“ZIM”)。也就是说,list应该以“VIR”开头“这并不意味着顺序应该颠倒,我想要像原始列表一样的顺序,意思是如果它以VIR开头,end list也应该以VIR开头,然后再合并