scala中映射的一对多关系

scala中映射的一对多关系,scala,scala-collections,Scala,Scala Collections,我是scala的新手。如何编写此函数getFilleOrder(),使其通过断言测试: case class Order(id:String, total:Double, lineItem:Seq[LineItem]) case class LineItem(id:String, productId:String) val order = Order("1", 10.0, Nil) val orderLineItemMap = Map(order->List(LineItem("1",

我是scala的新手。如何编写此函数getFilleOrder(),使其通过断言测试:

case class Order(id:String, total:Double, lineItem:Seq[LineItem])
case class LineItem(id:String, productId:String)


val order = Order("1", 10.0, Nil)
val orderLineItemMap = Map(order->List(LineItem("1", "prod1"),LineItem("2", "prod2")))
val filledOrder = getFilledOrder(orderLineItemMap)
assert(filledOrder ==  Order("1", 10.0, List(LineItem("1", "prod1"),LineItem("2", "prod2"))))
我试着写这样的东西:

def getFilledOrder(orderLineItemMap : Map[Order, List[LineItem]]):Order = { 
    orderLineItemMap.keys.foreach(order=> { 
      val filledOrder = Order(order.id, order.total, orderLineItemMap.get(order).get)
      println(filledOrder)
    })

}

这不会编译,因为函数没有返回订单。如何从foreach循环中获取filledOrder。提前谢谢

您最初的问题是需要使块返回一个
filledOrder
,这是通过使最后一个表达式
filledOrder
实现的,即在调用
println
之后

另一个问题是,
foreach
丢弃其结果。请尝试映射:

scala> val orderLineItemMap = Map("foo"->"bar", "baz"->"bat")
orderLineItemMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] =    Map(foo -> bar, baz -> bat)

scala> orderLineItemMap.keys.map(order => {
 |   val filledOrder = order.reverse
 |   println(filledOrder)
 |   filledOrder
 | })
oof
zab
res1: Iterable[String] = Set(oof, zab)

无论何时处理不可变的东西——在Scala中,通常情况下,
foreach
都是错误的。对于不可变数据,您可以将其用于输出,但不能用于其他用途

这将返回地图中包含的所有订单。您的代码假设映射只包含一个顺序,这意味着传递映射是愚蠢的

def getFilledOrder(orderLineMap: Map[Order, LineItem]) = orderLineItemMap.map { 
  case (order, lineItem) => order.copy(lineItem = lineItem) 
}

你的例子是在如此特殊的情况下,很难知道你想要你的函数做什么。假设地图上有两个键。(单个)结果顺序的id和总数应该是多少?很抱歉,我应该说明映射始终只有一个order对象键。foreach丢弃其函数参数的结果并返回unit。不行,不行。还是一样的错误。我想我不应该在这里用foreach?可能不会。您可以从foreach内部返回,但这肯定不是您应该做的。当您编写显式返回时,它将在字节码层上实现这一点,并抛出一个异常,该异常在foreach外部捕获,然后返回值。这绝对不是要走的路;-)。更新了答案,将
foreach
问题考虑在内。该方法有效。非常感谢你。我要做的唯一更改是将assert方法更改为filledOrder.head,因为新方法正在重新调整Iterable[Order]