Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge-left two lists?

Tags:

scala

Say that I have two case classes:

case class LineItem(name: String, price:Int, discount:Discount)
case class Discount(amount:Int, reason:String)

I have list of line items:

L1, L2, L3

and a list of discounts:

D1, D2

How can I merge the discounts into the list of line items?

I initially thought to just zip them and map but that drops L3 from the zipped list.

like image 575
wfg4 Avatar asked Jan 22 '26 17:01

wfg4


2 Answers

I would first convert the discounts to a list of Option[Discount], pad the list with Nones, zip it and map:

//items: List[LineItem], discounts: List[Discount]
val discOptions = discounts.map(Some(_)).padTo(items.length, None)

items.zip(discOptions) map {
  case (item, Some(disc)) => item.copy(discount = disc)
  case (item, None) => item
}
like image 105
Nicolò Martini Avatar answered Jan 25 '26 12:01

Nicolò Martini


zipLeft implemented similar to zipAll, but ignoring extra elements in right List.

def zipLeft[A, B](left: List[A], right: List[B], thatElem: B): List[(A, B)] = {
    val b = scala.collection.mutable.ListBuffer.empty[(A, B)]
    val these = left.iterator
    val those = right.iterator
    while (these.hasNext && those.hasNext)
      b += ((these.next(), those.next()))
    while (these.hasNext)
      b += ((these.next(), thatElem))
    b.toList
}
val lst1 = List(1,2,3)
val lst2 = List(4,5)
zipLeft(lst1,lst2,0)//List((1,4),(2,5),(3,0))
like image 37
Johny T Koshy Avatar answered Jan 25 '26 11:01

Johny T Koshy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!