根据条件压缩非顺序列表
Zip non sequential list based on condition
我有一个场景,我根据条件在 Scala 中压缩两个列表。
它们可能不按顺序排列。最好的方法是什么?
我想将具有相同 requestId 的 DirectRetailCM 和 DirectRetailCM 分组为一个元组。
object Main extends App {
case class SalesDoc(val id: Int, val name: String, val requestId: String) {}
val list = List(
SalesDoc(1, "ILLEGAL", "1"),
SalesDoc(2, "DirectRetailCM", "1"),
SalesDoc(3, "DirectRetailOffsetInvoice", "2"),
SalesDoc(4, "DirectRetailCM", "2"),
SalesDoc(5, "OTHER", "2"),
SalesDoc(5, "DirectRetailCM", "LEFTOUT"),
SalesDoc(6, "ILLEGAL2", "4"),
SalesDoc(5, "OTHER", "3"),
SalesDoc(7, "DirectRetailOffsetInvoice", "4"),
SalesDoc(8, "DirectRetailCM", "4")
)
// I expect zip results of drOffsetInvoice and drCms as
List(
(SalesDoc(3, "DirectRetailOffsetInvoice", "2"), SalesDoc(4, "DirectRetailCM", "2")),
(SalesDoc(7, "DirectRetailOffsetInvoice", "4"), SalesDoc(8, "DirectRetailCM", "4"))
)
}
我最初能想到的方法是
- group directRetailCM - list.filter(e => e.name == "DirectRetailCM")
- 组 DirectRetailOffsetInvoice - list.filter(e => e.name == "DirectRetailOffsetInvoice")
- 同时压缩 - 但可能不按顺序
- 可能有些行没有对应的行
您能否建议我需要考虑的任何其他方法?
// You don't need the val keyword for a case class
case class SalesDoc(id: Int, name: String, requestId: String)
val list = List(
SalesDoc(1, "ILLEGAL", "1"),
SalesDoc(2, "DirectRetailCM", "1"),
SalesDoc(3, "DirectRetailOffsetInvoice", "2"),
SalesDoc(4, "DirectRetailCM", "2"),
SalesDoc(5, "OTHER", "2"),
SalesDoc(5, "DirectRetailCM", "LEFTOUT"),
SalesDoc(6, "ILLEGAL2", "4"),
SalesDoc(5, "OTHER", "3"),
SalesDoc(7, "DirectRetailOffsetInvoice", "4"),
SalesDoc(8, "DirectRetailCM", "4")
)
// Find all of the DirectRetailOffsetInvoice items
val offsets = list.filter(_.name == "DirectRetailOffsetInvoice")
// Map over all of the DirectRetailOffsetInvoice items and see if there is matching DirectRetailCM item
val maybeMatched = offsets.map(offset => {
val maybeCm = list.find(i => i.requestId == offset.requestId && i.name == "DirectRetailCM")
// Return a tuple of type (SalesDoc, Option[SalesDoc])
(offset, maybeCm)
})
// Map over the tuples and only take the ones where there was a match, and extract it from the Option to create a tuple of (SalesDoc, SalesDoc)
val output = maybeMatched.collect { case (s1, Some(s2)) => (s1, s2) }
output.foreach(println)
// (SalesDoc(3,DirectRetailOffsetInvoice,2),SalesDoc(4,DirectRetailCM,2))
// (SalesDoc(7,DirectRetailOffsetInvoice,4),SalesDoc(8,DirectRetailCM,4))
list.filter(s => s.name == "DirectRetailCM" || s.name == "DirectRetailOffsetInvoice")
.groupBy(_.requestId)
.collect { case (_, List(a, b)) => (a, b) }
.toList
// List[(SalesDoc, SalesDoc)]
您可以使用标准 Scala 组合器实现此目的
list
.filter(sd => sd.name == "DirectRetailCM" || sd.name == "DirectRetailOffsetInvoice")
.groupBy(_.requestId)
.flatMap {
case (_, List(a,b)) => List(a->b)
case _ => List.empty
}
哪个给你:
res3: scala.collection.immutable.Map[SalesDoc,SalesDoc] =
Map(
SalesDoc(3,DirectRetailOffsetInvoice,2) -> SalesDoc(4,DirectRetailCM,2),
SalesDoc(7,DirectRetailOffsetInvoice,4) -> SalesDoc(8,DirectRetailCM,4))
如果输入序列不是DirectRetailOffsetInvoice
在DirectRetailCM
之前的排序,则需要处理它。
我有一个场景,我根据条件在 Scala 中压缩两个列表。 它们可能不按顺序排列。最好的方法是什么?
我想将具有相同 requestId 的 DirectRetailCM 和 DirectRetailCM 分组为一个元组。
object Main extends App {
case class SalesDoc(val id: Int, val name: String, val requestId: String) {}
val list = List(
SalesDoc(1, "ILLEGAL", "1"),
SalesDoc(2, "DirectRetailCM", "1"),
SalesDoc(3, "DirectRetailOffsetInvoice", "2"),
SalesDoc(4, "DirectRetailCM", "2"),
SalesDoc(5, "OTHER", "2"),
SalesDoc(5, "DirectRetailCM", "LEFTOUT"),
SalesDoc(6, "ILLEGAL2", "4"),
SalesDoc(5, "OTHER", "3"),
SalesDoc(7, "DirectRetailOffsetInvoice", "4"),
SalesDoc(8, "DirectRetailCM", "4")
)
// I expect zip results of drOffsetInvoice and drCms as
List(
(SalesDoc(3, "DirectRetailOffsetInvoice", "2"), SalesDoc(4, "DirectRetailCM", "2")),
(SalesDoc(7, "DirectRetailOffsetInvoice", "4"), SalesDoc(8, "DirectRetailCM", "4"))
)
}
我最初能想到的方法是
- group directRetailCM - list.filter(e => e.name == "DirectRetailCM")
- 组 DirectRetailOffsetInvoice - list.filter(e => e.name == "DirectRetailOffsetInvoice")
- 同时压缩 - 但可能不按顺序
- 可能有些行没有对应的行
您能否建议我需要考虑的任何其他方法?
// You don't need the val keyword for a case class
case class SalesDoc(id: Int, name: String, requestId: String)
val list = List(
SalesDoc(1, "ILLEGAL", "1"),
SalesDoc(2, "DirectRetailCM", "1"),
SalesDoc(3, "DirectRetailOffsetInvoice", "2"),
SalesDoc(4, "DirectRetailCM", "2"),
SalesDoc(5, "OTHER", "2"),
SalesDoc(5, "DirectRetailCM", "LEFTOUT"),
SalesDoc(6, "ILLEGAL2", "4"),
SalesDoc(5, "OTHER", "3"),
SalesDoc(7, "DirectRetailOffsetInvoice", "4"),
SalesDoc(8, "DirectRetailCM", "4")
)
// Find all of the DirectRetailOffsetInvoice items
val offsets = list.filter(_.name == "DirectRetailOffsetInvoice")
// Map over all of the DirectRetailOffsetInvoice items and see if there is matching DirectRetailCM item
val maybeMatched = offsets.map(offset => {
val maybeCm = list.find(i => i.requestId == offset.requestId && i.name == "DirectRetailCM")
// Return a tuple of type (SalesDoc, Option[SalesDoc])
(offset, maybeCm)
})
// Map over the tuples and only take the ones where there was a match, and extract it from the Option to create a tuple of (SalesDoc, SalesDoc)
val output = maybeMatched.collect { case (s1, Some(s2)) => (s1, s2) }
output.foreach(println)
// (SalesDoc(3,DirectRetailOffsetInvoice,2),SalesDoc(4,DirectRetailCM,2))
// (SalesDoc(7,DirectRetailOffsetInvoice,4),SalesDoc(8,DirectRetailCM,4))
list.filter(s => s.name == "DirectRetailCM" || s.name == "DirectRetailOffsetInvoice")
.groupBy(_.requestId)
.collect { case (_, List(a, b)) => (a, b) }
.toList
// List[(SalesDoc, SalesDoc)]
您可以使用标准 Scala 组合器实现此目的
list
.filter(sd => sd.name == "DirectRetailCM" || sd.name == "DirectRetailOffsetInvoice")
.groupBy(_.requestId)
.flatMap {
case (_, List(a,b)) => List(a->b)
case _ => List.empty
}
哪个给你:
res3: scala.collection.immutable.Map[SalesDoc,SalesDoc] =
Map(
SalesDoc(3,DirectRetailOffsetInvoice,2) -> SalesDoc(4,DirectRetailCM,2),
SalesDoc(7,DirectRetailOffsetInvoice,4) -> SalesDoc(8,DirectRetailCM,4))
如果输入序列不是DirectRetailOffsetInvoice
在DirectRetailCM
之前的排序,则需要处理它。