4

I need to implement a "zipLongest" function in Scala; that is, combine two sequences together as pairs, and if one is longer than the other, use a default value. (Unlike the standard zip method, which will just truncate to the shortest sequence.)

I've implemented it directly as follows:

def zipLongest[T](xs: Seq[T], ys: Seq[T], default: T): Seq[(T, T)] = (xs, ys) match { case (Seq(), Seq()) => Seq() case (Seq(), y +: rest) => (default, y) +: zipLongest(Seq(), rest, default) case (x +: rest, Seq()) => (x, default) +: zipLongest(rest, Seq(), default) case (x +: restX, y +: restY) => (x, y) +: zipLongest(restX, restY, default) } 

Is there a better way to do it?

2 Answers 2

8

Use zipAll :

scala> val l1 = List(1,2,3) l1: List[Int] = List(1, 2, 3) scala> val l2 = List("a","b") l2: List[String] = List(a, b) scala> l1.zipAll(l2,0,".") res0: List[(Int, String)] = List((1,a), (2,b), (3,.)) 

If you want to use the same default value for the first and second seq :

scala> def zipLongest[T](xs:Seq[T], ys:Seq[T], default:T) = xs.zipAll(ys, default, default) zipLongest: [T](xs: Seq[T], ys: Seq[T], default: T)Seq[(T, T)] scala> val l3 = List(4,5,6,7) l3: List[Int] = List(4, 5, 6, 7) scala> zipLongest(l1,l3,0) res1: Seq[(Int, Int)] = List((1,4), (2,5), (3,6), (0,7)) 
Sign up to request clarification or add additional context in comments.

Comments

6

You can do this as a oneliner:

xs.padTo(ys.length, x).zip(ys.padTo(xs.length, y)) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.