Reputation: 2797
I want to clean fields of some objects which are part of collections(setting to None). Below is the class hierarchy and their structures
final case class OrderItem(
simpleSku: String,
merchant: Option[String])
final case class OrderItemGroup(id: String,
items: Seq[OrderItem],
fType: Option[String])
final case class OrderRequest(groups: Seq[OrderItemGroup])
val orderItem1 = OrderItem("simple1",Some("merchant1"))
val salesOrderItem2 = OrderItem("simple2",Some("merchant2"))
val salesOrderItem3 = OrderItem("simple3",Some("merchant3"))
val c1 = OrderItemGroup("id1",Seq(orderItem1,salesOrderItem3),Some("fulfillmentA"))
val c2 = OrderItemGroup("id2",Seq(orderItem1,salesOrderItem2),Some("fulfillmentB"))
val o = OrderRequest(Seq(c1,c2))
I basically want to clean fields merchant and fType and come up with the following code but its multiplying inner items. How can this be done with .copy approach?
def clearFields (orderRequest:OrderRequest) :OrderRequest = {
val items = orderRequest.groups.flatMap(x => x.items)
println("items" + items)
val groups = orderRequest.groups
val r = orderRequest.copy(groups = groups.map(_.copy(fType = None, items = items.map(_.copy(merchant = None)))))
r
}
Upvotes: 0
Views: 55
Reputation: 48420
Monocle is helpful when we have to copy such nested structures, for example,
import monocle.Traversal
import monocle.macros.GenLens
import cats.implicits._
val cleanMerchant = GenLens[OrderItem](_.merchant).set(None)
val cleanFType = GenLens[OrderItemGroup](_.fType).set(None)
val cleanGroupItems = Traversal.fromTraverse[List, OrderItemGroup].modify(g => g.copy(items = g.items.map(cleanMerchant)))
OrderRequest(cleanGroupItems(o.groups.toList).map(cleanFType))
outputs
OrderRequest(List(OrderItemGroup(id1,List(OrderItem(simple1,None), OrderItem(simple3,None)),None), OrderItemGroup(id2,List(OrderItem(simple1,None), OrderItem(simple2,None)),None)))
To clean it using vanilla Scala try
def cleanOrderItemGroup(group: OrderItemGroup): OrderItemGroup = {
val items = group.items
val cleanItems = items.map(cleanOrderItem)
group.copy(items = cleanItems, fType = None)
}
def cleanOrderItem(item: OrderItem): OrderItem = {
item.copy(merchant = None)
}
OrderRequest(o.groups.map(cleanOrderItemGroup))
which again outputs
OrderRequest(List(OrderItemGroup(id1,List(OrderItem(simple1,None), OrderItem(simple3,None)),None), OrderItemGroup(id2,List(OrderItem(simple1,None), OrderItem(simple2,None)),None)))
Upvotes: 3