有没有更惯用的方法来简化 leftJoin 的结果?
Is there a more idiomatic way to simplify the results of a leftJoin?
我正在开发 Scala 2.12.x 和 Slick 3.3.0 项目,我有一个处理 joinLeft
操作结果的重复用例。
左连接给我这样的结果:Future[Seq[(A, Option[B])]]
其中 A
是主控类型 - table 和 B
是细节 -table 的类型。换句话说,我得到了主元素 A
的序列,重复了与 B
的左连接实例一样多的次数。我想将这种复杂的重复类型简化为更易于管理的结果类型 Future[Option[(A, Seq[B])]]
。为此我创建了以下函数:
implicit def simplify[A, B](x: Future[Seq[(A, Option[B])]])(implicit ec: ExecutionContext): Future[Option[(A, Seq[B])]] = {
x.map {
case results => {
val seq: Seq[B] = results.map(_._2).map {
case Some(b) => Some(b)
case _ => None.asInstanceOf[Option[B]]
}.filterNot(_.isEmpty).map(_.get) match {
case seq if (seq.nonEmpty) => seq
case _ => Seq()
}
results.headOption.map {
case (a, _) => (a, seq)
}
}
}
}
但它看起来有点太复杂而且它没有说明可能有多个 A
实例的事实,例如
a1 b11
a1 b12
a1 b13
a2 b21
a2 b22
请注意,在这种情况下,我的函数会给出错误的结果:Future[Some((a1, Seq(b11, b12, b13, b21, b22)))]
,正确的结果是 Future[Some((a1, Seq(b11, b12, b13)))]
如何让它更简单更正确?
如果要将 A 值与定义的所有相应 B 值组合,可以使用 groupBy(_._1)
按元组的第一个元素分组,然后通过应用 mapValues(_.flatMap(_._2))
def simplify[A, B](x: Future[Seq[(A, Option[B])]])(implicit ec: ExecutionContext)
: Future[Map[A, Seq[B]]] =
x.map(_.groupBy(_._1).mapValues(_.flatMap(_._2)))
我将 return 类型更改为 Future[Map[A, Seq[B]]]
以允许不同的 A 值
我正在开发 Scala 2.12.x 和 Slick 3.3.0 项目,我有一个处理 joinLeft
操作结果的重复用例。
左连接给我这样的结果:Future[Seq[(A, Option[B])]]
其中 A
是主控类型 - table 和 B
是细节 -table 的类型。换句话说,我得到了主元素 A
的序列,重复了与 B
的左连接实例一样多的次数。我想将这种复杂的重复类型简化为更易于管理的结果类型 Future[Option[(A, Seq[B])]]
。为此我创建了以下函数:
implicit def simplify[A, B](x: Future[Seq[(A, Option[B])]])(implicit ec: ExecutionContext): Future[Option[(A, Seq[B])]] = {
x.map {
case results => {
val seq: Seq[B] = results.map(_._2).map {
case Some(b) => Some(b)
case _ => None.asInstanceOf[Option[B]]
}.filterNot(_.isEmpty).map(_.get) match {
case seq if (seq.nonEmpty) => seq
case _ => Seq()
}
results.headOption.map {
case (a, _) => (a, seq)
}
}
}
}
但它看起来有点太复杂而且它没有说明可能有多个 A
实例的事实,例如
a1 b11
a1 b12
a1 b13
a2 b21
a2 b22
请注意,在这种情况下,我的函数会给出错误的结果:Future[Some((a1, Seq(b11, b12, b13, b21, b22)))]
,正确的结果是 Future[Some((a1, Seq(b11, b12, b13)))]
如何让它更简单更正确?
如果要将 A 值与定义的所有相应 B 值组合,可以使用 groupBy(_._1)
按元组的第一个元素分组,然后通过应用 mapValues(_.flatMap(_._2))
def simplify[A, B](x: Future[Seq[(A, Option[B])]])(implicit ec: ExecutionContext)
: Future[Map[A, Seq[B]]] =
x.map(_.groupBy(_._1).mapValues(_.flatMap(_._2)))
我将 return 类型更改为 Future[Map[A, Seq[B]]]
以允许不同的 A 值