根据条件压缩非顺序列表

时间:2017-08-15 12:54:32

标签: scala scala-collections scalaz

我有一个场景,我根据条件在scala中压缩两个列表。 它们可能不是按顺序排列的。最好的方法是什么?

我想将DirectRetailCM和DirectRetailCM分组为具有相同的requestId作为元组。

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")
  • group DirectRetailOffsetInvoice - list.filter(e => e.name ==" DirectRetailOffsetInvoice")
  • 拉链 - 但可能不是按顺序
  • 可能会有不具备对应字体的行

您能否提出我需要考虑的其他方法?

3 个答案:

答案 0 :(得分:2)

// 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))

答案 1 :(得分:1)

header ‘Access-Control-Allow-Origin’ missing

答案 2 :(得分:1)

您可以使用标准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排序,则需要处理它。

相关问题