Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate TraversableOnce objects in Scala?

I want to concatenate a traversable once to a traversable once without resolving either. This is the solution I have come up with as an implicit, but I don't know if I am missing a native solution...

object ImplicitTraversableOnce {
  implicit def extendTraversableOnce[T](t : TraversableOnce[T]) = new TraversableOnceExtension(t)
}

class TraversableOnceExtension[T <: Any](t : TraversableOnce[T]) {

  def ++ (t2:TraversableOnce[T]):TraversableOnce[T] = new concat(t.toIterator, t2.toIterator)

  private class concat(i1:Iterator[T], i2:Iterator[T]) extends Iterator[T] {
    private var isOnSecond = false

    def hasNext:Boolean =
      if (isOnSecond) i2.hasNext
      else if (!i1.hasNext) {
        isOnSecond = true
        hasNext
      }
    else true

    def next():T = if (isOnSecond) i2.next() else i1.next()
  }
}
like image 961
J Pullar Avatar asked Dec 21 '22 14:12

J Pullar


2 Answers

You can join iterators with ++. So if you're going to use iterators anyway, just

def ++(t2: TraversableOnce[T]): TraversableOnce[T] = t.toIterator ++ t2.toIterator

The reason to not do this is to supply an efficient foreach for Traversables that are not Iterable/Iterator, but then you need to fill in all the TraversableOnce abstract methods.

like image 183
Rex Kerr Avatar answered Dec 29 '22 00:12

Rex Kerr


How about:

  def ++(t2: TraversableOnce[T]) = new Traversable[T] {
    def foreach[U](f: (T) => U) {
      t.foreach(f)
      t2.foreach(f)
    }
  }
like image 43
Wilfred Springer Avatar answered Dec 28 '22 22:12

Wilfred Springer