已排序集合上id为的Scala zip

已排序集合上id为的Scala zip,scala,functional-programming,Scala,Functional Programming,我在scala中有两个集合,其中的对象包含id。我想按id将它们压缩在一起。因此在这样的示例中: case class A(id: Long) case class B(id: Long) val col1 = A(1) :: A(2) :: A(5) :: Nil val col2 = B(2) :: B(2) :: B(5) :: Nil 我希望结果是: List( (A(1), List()), (A(2), List(B(2), B(2)), (A(5)

我在scala中有两个集合,其中的对象包含id。我想按id将它们压缩在一起。因此在这样的示例中:

case class A(id: Long)
case class B(id: Long)

val col1 = A(1) :: A(2) :: A(5) :: Nil
val col2 = B(2) :: B(2) :: B(5) :: Nil
我希望结果是:

List(
     (A(1), List()),
     (A(2), List(B(2), B(2)),
     (A(5), List(B(5))
    )
如何用简单的方法来做?
如果我知道col1和col2已经按id排序,会有什么帮助吗?

一种方法是将第一个集合映射到
映射中,然后在
映射中对第二个集合进行
筛选并构建元组:

scala> col1.map { c1 =>
     |     (c1, col2.filter(_.id == c1.id))
     |   }
res0: List[(A, List[B])] = List((A(1),List()), (A(2),List(B(2), B(2))), (A(5),List(B(5))))

一种方法是对第一个集合进行
映射
并在
映射
中对第二个集合进行
筛选
,然后构建元组:

scala> col1.map { c1 =>
     |     (c1, col2.filter(_.id == c1.id))
     |   }
res0: List[(A, List[B])] = List((A(1),List()), (A(2),List(B(2), B(2))), (A(5),List(B(5))))

如果没有中间变量,我想不出一个好方法,但是像这样的方法怎么样:

val map = col2.groupBy(_.id).withDefault(_ => List.empty)
col1.map { a => a -> map(a.id) }

对于三元素阵列来说,这并不重要,但请注意,与其他答案的主要区别在于,这是线性时间。

如果没有中间变量,我想不出一个好方法,但是类似这样的方法如何:

val map = col2.groupBy(_.id).withDefault(_ => List.empty)
col1.map { a => a -> map(a.id) }
对于三元素阵列,这并不重要,但请注意,与其他答案的主要区别在于,这是线性时间