user4165421
user4165421

Reputation: 131

Merging streams in scala

I need help with merging two streams into one. The output has to be as follows:

(elem1list1#elem1list2, elem2list1#elem2list2...) 

and the function breaks if any of streams is empty

def mergeStream(a: Stream[A], b: Stream[A]):Stream[A] = 
if (a.isEmpty || b.isEmpty) Nil
else (a,b) match {
case(x#::xs, y#::ys) => x#::y
}

Any clue how to fix it?

Upvotes: 3

Views: 2743

Answers (3)

stew
stew

Reputation: 11366

You can use interleave from scalaz:

scala> (Stream(1,2) interleave Stream.from(10)).take(10).force
res1: scala.collection.immutable.Stream[Int] = Stream(1, 10, 2, 11, 12, 13, 14, 15, 16, 17)

Upvotes: 2

Michael Zajac
Michael Zajac

Reputation: 55569

You can also zip two Streams together, which will truncate the longer Stream, and flatMap them out of the tuples:

a.zip(b).flatMap { case (a, b) => Stream(a, b) }

Though I cannot speak to it's efficiency.

scala> val a = Stream(1,2,3,4)
a: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> val b = Stream.from(3)
b: scala.collection.immutable.Stream[Int] = Stream(3, ?)

scala> val c = a.zip(b).flatMap { case (a, b) => Stream(a, b) }.take(10).toList
c: List[Int] = List(1, 3, 2, 4, 3, 5, 4, 6)

Upvotes: 3

j-keck
j-keck

Reputation: 1031

def mergeStream(s1: Stream[Int], s2: Stream[Int]): Stream[Int] = (s1, s2) match {
  case (x#::xs, y#::ys) => x #:: y #:: mergeStream(xs, ys)
  case _ => Stream.empty
}

scala> mergeStream(Stream.from(1), Stream.from(100)).take(10).toList
res0: List[Int] = List(1, 100, 2, 101, 3, 102, 4, 103, 5, 104)

Upvotes: 2

Related Questions