All Downloads are FREE. Search and download functionalities are using the official Maven repository.

au.id.tmm.utilities.collection.syntax.IteratorOps.scala Maven / Gradle / Ivy

There is a newer version: 0.4.7
Show newest version
package au.id.tmm.utilities.collection.syntax

import scala.annotation.tailrec
import scala.collection.mutable

final class IteratorOps[+A] private[syntax] (iterator: Iterator[A]) {

  /**
    * Reads either the next `n` elements of the iterator, or to its end, whichever comes first. This method differs
    * from `scala.collection.Iterator.take`, in that it simply reads the elements from the underlying iterator,
    * leaving it free for continued use after the invocation.
    * @return the elements read from the iterator
    */
  def readAtMost(n: Int): Vector[A] = {
    val result: mutable.ArrayBuffer[A] = new mutable.ArrayBuffer(n)

    while (result.size < n && iterator.hasNext) {
      result += iterator.next()
    }

    result.toVector
  }

  /**
    * Reads until the given condition is satisfied, or until the end of the iterator. This method differs from
    * `scala.collection.Iterable.dropWhile`, in that it simply reads the elements from the underlying iterator,
    * leaving it free for continued use after the invocation.
    * @return the elements read before the condition is met or the iterator is exhausted
    */
  def readUntil(p: A => Boolean): Vector[A] = {
    val result: mutable.ArrayBuffer[A] = mutable.ArrayBuffer()

    @tailrec
    def readMore(): Unit =
      if (iterator.hasNext) {
        val element = iterator.next()

        result += element

        if (!p(element)) {
          readMore()
        }
      }

    readMore()

    result.toVector
  }

  /**
    * Reads from the iterator until either the given number of elements have been read, the given condition has been
    * satisfied, or the iterator is exhausted. The underlying iterator can continue to be used after this method
    * returns.
    * @param n the maximum number of elements to read from the iterator
    * @param p a condition if, when satisfied, stops the consumption of the iterator
    * @return the elements read from the iterator
    */
  def readAtMostUntil(n: Int, p: A => Boolean): Vector[A] = {
    val result: mutable.ArrayBuffer[A] = new mutable.ArrayBuffer[A](n)

    @tailrec
    def readMore(): Unit =
      if (iterator.hasNext) {
        val element = iterator.next()

        result += element

        if (!p(element) && result.size < n) {
          readMore()
        }
      }

    readMore()

    result.toVector
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy