Anjan Pathak
Anjan Pathak

Reputation: 11

one to many relation from a map in scala

I am a newbie in scala. How do I write this function getFilledOrder() so that it passes the assert test:

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

I am trying to write something like this:

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

}

This doesn't compile as the function is not returning an Order. How do I get the filledOrder out of the foreach loop. Thanks in advance.

Upvotes: 0

Views: 551

Answers (2)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297205

Whenever you are dealing with immutable stuff -- and, in Scala, you usually are, foreach is the wrong thing to do. With immutable data, you can use it for output, but nothing else.

This returns all orders contained in the map. Your code assumes the map contains only one order, which means passing a map at all is silly.

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

Upvotes: 1

Larry OBrien
Larry OBrien

Reputation: 8606

Your initial problem is that you need to make your block return a filledOrder, which you do by making the last expression filledOrder, i.e., after the call to println.

The other problem is that foreach discards its result. Try map instead:

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)

Upvotes: 0

Related Questions