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

izumi.fundamentals.collections.nonempty.NEList.scala Maven / Gradle / Ivy

The newest version!
package izumi.fundamentals.collections.nonempty

// shameless copypaste from Scalactic

import scala.collection.compat.*
import scala.collection.mutable.{ArrayBuffer, Buffer}
import scala.collection.{Iterable, Seq, mutable}
import scala.language.implicitConversions
import scala.reflect.ClassTag

final class NEList[+T] private (val toList: List[T]) extends AnyVal {

  /**
    * Returns a new NEList containing the elements of this NEList followed by the elements of the passed NEList.
    * The element type of the resulting NEList is the most specific superclass encompassing the element types of this and the passed NEList.
    *
    * @tparam U the element type of the returned NEList
    * @param other the NEList to append
    * @return a new NEList that contains all the elements of this NEList followed by all elements of other.
    */
  def ++[U >: T](other: NEList[U]): NEList[U] = new NEList(toList ++ other.toList)

  /**
    * Returns a new NEList containing the elements of this NEList followed by the elements of the passed Vector.
    * The element type of the resulting NEList is the most specific superclass encompassing the element types of this NEList and the passed Vector.
    *
    * @tparam U the element type of the returned NEList
    * @param other the Vector to append
    * @return a new NEList that contains all the elements of this NEList followed by all elements of other.
    */
  def ++[U >: T](other: Vector[U]): NEList[U] = new NEList(toList ++ other)

  // TODO: Have I added these extra ++, etc. methods to Vector that take a NEList?

  /**
    * Returns a new NEList containing the elements of this NEList followed by the elements of the passed GenTraversableOnce.
    * The element type of the resulting NEList is the most specific superclass encompassing the element types of this NEList
    * and the passed GenTraversableOnce.
    *
    * @tparam U the element type of the returned NEList
    * @param other the GenTraversableOnce to append
    * @return a new NEList that contains all the elements of this NEList followed by all elements of other.
    */
  def ++[U >: T](other: IterableOnce[U]): NEList[U] = {
    val it = other.iterator
    if (it.isEmpty) this else new NEList(toList ++ it)
  }

  @inline def ++:[U >: T](other: NEList[U]): NEList[U] = other ::: this
  @inline def ++:[U >: T](other: Vector[U]): NEList[U] = other ::: this
  @inline def ++:[U >: T](other: IterableOnce[U]): NEList[U] = other ::: this

  /**
    * Returns a new NEList with the given element prepended.
    *
    * 

* Note that :-ending operators are right associative. A mnemonic for +: vs. :+ is: the COLon goes on the COLlection side. *

* * @param element the element to prepend to this NEList * @return a new NEList consisting of element followed by all elements of this NEList. */ def +:[U >: T](element: U): NEList[U] = new NEList(element :: toList) /** * Adds an element to the beginning of this NEList. * *

* Note that :-ending operators are right associative. A mnemonic for +: vs. :+ is: the COLon goes on the COLlection side. *

* * @param element the element to prepend to this NEList * @return a NEList that contains element as first element and that continues with this NEList. */ def ::[U >: T](element: U): NEList[U] = new NEList(element :: toList) /** * Returns a new NEList containing the elements of this NEList followed by the elements of the passed NEList. * The element type of the resulting NEList is the most specific superclass encompassing the element types of this and the passed NEList. * * @tparam U the element type of the returned NEList * @param other the NEList to append * @return a new NEList that contains all the elements of this NEList followed by all elements of other. */ def :::[U >: T](other: NEList[U]): NEList[U] = new NEList(other.toList ::: toList) /** * Returns a new NEList containing the elements of this NEList followed by the elements of the passed Vector. * The element type of the resulting NEList is the most specific superclass encompassing the element types of this and the passed Vector. * * @tparam U the element type of the returned NEList * @param other the Vector to append * @return a new NEList that contains all the elements of this NEList followed by all elements of other. */ def :::[U >: T](other: Vector[U]): NEList[U] = new NEList(other.toList ::: toList) /** * Returns a new NEList containing the elements of this NEList followed by the elements of the passed GenTraversableOnce. * The element type of the resulting NEList is the most specific superclass encompassing the element types of this NEList * and the passed GenTraversableOnce. * * @tparam U the element type of the returned NEList * @param other the GenTraversableOnce to append * @return a new NEList that contains all the elements of this NEList followed by all elements of other. */ def :::[U >: T](other: IterableOnce[U]): NEList[U] = { val it = other.iterator if (it.isEmpty) this else new NEList(it.toList ::: toList) } /** * Returns a new NEList with the given element appended. * *

* Note a mnemonic for +: vs. :+ is: the COLon goes on the COLlection side. *

* * @param element the element to append to this NEList * @return a new NEList consisting of all elements of this NEList followed by element. */ def :+[U >: T](element: U): NEList[U] = new NEList(toList :+ element) /** * Appends all elements of this NEList to a string builder. The written text will consist of a concatenation of the result of invoking toString * on of every element of this NEList, without any separator string. * * @param sb the string builder to which elements will be appended * @return the string builder, sb, to which elements were appended. */ def addString(sb: StringBuilder): StringBuilder = toList.addString(sb) /** * Appends all elements of this NEList to a string builder using a separator string. The written text will consist of a concatenation of the * result of invoking toString * on of every element of this NEList, separated by the string sep. * * @param sb the string builder to which elements will be appended * @param sep the separator string * @return the string builder, sb, to which elements were appended. */ def addString(sb: StringBuilder, sep: String): StringBuilder = toList.addString(sb, sep) /** * Appends all elements of this NEList to a string builder using start, end, and separator strings. The written text will consist of a concatenation of * the string start; the result of invoking toString on all elements of this NEList, * separated by the string sep; and the string end * * @param sb the string builder to which elements will be appended * @param start the starting string * @param sep the separator string * @param start the ending string * @return the string builder, sb, to which elements were appended. */ def addString(sb: StringBuilder, start: String, sep: String, end: String): StringBuilder = toList.addString(sb, start, sep, end) /** * Selects an element by its index in the NEList. * * @return the element of this NEList at index idx, where 0 indicates the first element. */ def apply(idx: Int): T = toList(idx) /** * Finds the first element of this NEList for which the given partial function is defined, if any, and applies the partial function to it. * * @param pf the partial function * @return an Option containing pf applied to the first element for which it is defined, or None if * the partial function was not defined for any element. */ def collectFirst[U](pf: PartialFunction[T, U]): Option[U] = toList.collectFirst(pf) /** * Indicates whether this NEList contains a given value as an element. * * @param elem the element to look for * @return true if this NEList has an element that is equal (as determined by ==) to elem, false otherwise. */ infix def contains(elem: Any): Boolean = toList.contains(elem) /** * Indicates whether this NEList contains a given Seq as a slice. * * @param that the Seq slice to look for * @return true if this NEList contains a slice with the same elements as that, otherwise false. */ def containsSlice[U >: T](that: Seq[U]): Boolean = toList.containsSlice(that) /** * Indicates whether this NEList contains a given Vector as a slice. * * @param that the Vector slice to look for * @return true if this NEList contains a slice with the same elements as that, otherwise false. */ def containsSlice[U >: T](that: Vector[U]): Boolean = toList.containsSlice(that) /** * Indicates whether this NEList contains a given NEList as a slice. * * @param that the NEList slice to look for * @return true if this NEList contains a slice with the same elements as that, otherwise false. */ def containsSlice[U >: T](that: NEList[U]): Boolean = toList.containsSlice(that.toList) /** * Copies values of this NEList to an array. Fills the given array arr with values of this NEList. Copying * will stop once either the end of the current NEList is reached, or the end of the array is reached. * * @param arr the array to fill */ def copyToArray[U >: T](arr: Array[U]): Unit = { toList.copyToArray(arr) () } /** * Copies values of this NEList to an array. Fills the given array arr with values of this NEList, beginning at * index start. Copying will stop once either the end of the current NEList is reached, or the end of the array is reached. * * @param arr the array to fill * @param start the starting index */ def copyToArray[U >: T](arr: Array[U], start: Int): Unit = { toList.copyToArray(arr, start) () } /** * Copies values of this NEList to an array. Fills the given array arr with at most len elements of this NEList, beginning at * index start. Copying will stop once either the end of the current NEList is reached, the end of the array is reached, or * len elements have been copied. * * @param arr the array to fill * @param start the starting index * @param len the maximum number of elements to copy */ def copyToArray[U >: T](arr: Array[U], start: Int, len: Int): Unit = { toList.copyToArray(arr, start, len) () } /** * Copies all elements of this NEList to a buffer. * * @param buf the buffer to which elements are copied */ def copyToBuffer[U >: T](buf: Buffer[U]): Unit = { buf ++= toList // toList.copyToBuffer(buf) } /** * Indicates whether every element of this NEList relates to the corresponding element of a given Seq by satisfying a given predicate. * * @tparam B the type of the elements of that * @param that the Seq to compare for correspondence * @param p the predicate, which relates elements from this NEList and the passed Seq * @return true if this NEList and the passed Seq have the same length and p(x, y) is true * for all corresponding elements x of this NEList and y of that, otherwise false. */ def corresponds[B](that: Seq[B])(p: (T, B) => Boolean): Boolean = toList.corresponds(that)(p) /** * Indicates whether every element of this NEList relates to the corresponding element of a given Vector by satisfying a given predicate. * * @tparam B the type of the elements of that * @param that the Vector to compare for correspondence * @param p the predicate, which relates elements from this NEList and the passed Vector * @return true if this NEList and the passed Vector have the same length and p(x, y) is true * for all corresponding elements x of this NEList and y of that, otherwise false. */ def corresponds[B](that: Vector[B])(p: (T, B) => Boolean): Boolean = toList.corresponds(that)(p) /** * Indicates whether every element of this NEList relates to the corresponding element of a given NEList by satisfying a given predicate. * * @tparam B the type of the elements of that * @param that the NEList to compare for correspondence * @param p the predicate, which relates elements from this and the passed NEList * @return true if this and the passed NEList have the same length and p(x, y) is true * for all corresponding elements x of this NEList and y of that, otherwise false. */ def corresponds[B](that: NEList[B])(p: (T, B) => Boolean): Boolean = toList.corresponds(that.toList)(p) /** * Counts the number of elements in this NEList that satisfy a predicate. * * @param p the predicate used to test elements. * @return the number of elements satisfying the predicate p. */ def count(p: T => Boolean): Int = toList.count(p) /** * Builds a new NEList from this NEList without any duplicate elements. * * @return A new NEList that contains the first occurrence of every element of this NEList. */ def distinct: NEList[T] = new NEList(toList.distinct) /** * Indicates whether this NEList ends with the given Seq. * * @param that the sequence to test * @return true if this NEList has that as a suffix, false otherwise. */ def endsWith[B](that: Seq[B]): Boolean = toList.endsWith[Any](that) /** * Indicates whether this NEList ends with the given Vector. * * @param that the Vector to test * @return true if this NEList has that as a suffix, false otherwise. */ def endsWith[B](that: Vector[B]): Boolean = toList.endsWith[Any](that) // TODO: Search for that: Vector in here and add a that: NEList in Vector. /** * Indicates whether this NEList ends with the given NEList. * * @param that the NEList to test * @return true if this NEList has that as a suffix, false otherwise. */ def endsWith[B](that: NEList[B]): Boolean = toList.endsWith[Any](that.toList) /* override def equals(o: Any): Boolean = o match { case NEList: NEList[?] => toList == NEList.toList case _ => false } */ /** * Indicates whether a predicate holds for at least one of the elements of this NEList. * * @param the predicate used to test elements. * @return true if the given predicate p holds for some of the elements of this NEList, otherwise false. */ def exists(p: T => Boolean): Boolean = toList.exists(p) /** * Finds the first element of this NEList that satisfies the given predicate, if any. * * @param p the predicate used to test elements * @return an Some containing the first element in this NEList that satisfies p, or None if none exists. */ def find(p: T => Boolean): Option[T] = toList.find(p) /** * Builds a new NEList by applying a function to all elements of this NEList and using the elements of the resulting NELists. * * @tparam U the element type of the returned NEList * @param f the function to apply to each element. * @return a new NEList containing elements obtained by applying the given function f to each element of this NEList and concatenating * the elements of resulting NELists. */ def flatMap[U](f: T => NEList[U]): NEList[U] = { val buf = new ArrayBuffer[U] for (ele <- toList) buf ++= f(ele).toList new NEList(buf.toList) } /** * Converts this NEList of NELists into a NEList * formed by the elements of the nested NELists. * *

* @note You cannot use this flatten method on a NEList that contains a GenTraversableOnces, because * if all the nested GenTraversableOnces were empty, you'd end up with an empty NEList. *

* * @tparm B the type of the elements of each nested NEList * @return a new NEList resulting from concatenating all nested NELists. */ def flatten[B](implicit ev: T <:< NEList[B]): NEList[B] = flatMap(ev) /** * Folds the elements of this NEList using the specified associative binary operator. * *

* The order in which operations are performed on elements is unspecified and may be nondeterministic. *

* * @tparam U a type parameter for the binary operator, a supertype of T. * @param z a neutral element for the fold operation; may be added to the result an arbitrary number of * times, and must not change the result (e.g., Nil for list concatenation, * 0 for addition, or 1 for multiplication.) * @param op a binary operator that must be associative * @return the result of applying fold operator op between all the elements and z */ def fold[U >: T](z: U)(op: (U, U) => U): U = toList.fold(z)(op) /** * Applies a binary operator to a start value and all elements of this NEList, going left to right. * * @tparam B the result type of the binary operator. * @param z the start value. * @param op the binary operator. * @return the result of inserting op between consecutive elements of this NEList, going left to right, with the start value, * z, on the left: * *
    * op(...op(op(z, x_1), x_2), ..., x_n)
    * 
* *

* where x1, ..., xn are the elements of this NEList. *

*/ def foldLeft[B](z: B)(op: (B, T) => B): B = toList.foldLeft(z)(op) /** * Applies a binary operator to all elements of this NEList and a start value, going right to left. * * @tparam B the result of the binary operator * @param z the start value * @param op the binary operator * @return the result of inserting op between consecutive elements of this NEList, going right to left, with the start value, * z, on the right: * *
    * op(x_1, op(x_2, ... op(x_n, z)...))
    * 
* *

* where x1, ..., xn are the elements of this NEList. *

*/ def foldRight[B](z: B)(op: (T, B) => B): B = toList.foldRight(z)(op) /** * Indicates whether a predicate holds for all elements of this NEList. * * @param p the predicate used to test elements. * @return true if the given predicate p holds for all elements of this NEList, otherwise false. */ def forall(p: T => Boolean): Boolean = toList.forall(p) /** * Applies a function f to all elements of this NEList. * * @param f the function that is applied for its side-effect to every element. The result of function f is discarded. */ def foreach(f: T => Unit): Unit = toList.foreach(f) /** * Partitions this NEList into a map of NELists according to some discriminator function. * * @tparam K the type of keys returned by the discriminator function. * @param f the discriminator function. * @return A map from keys to NELists such that the following invariant holds: * *
    * (NEList.toList partition f)(k) = xs filter (x => f(x) == k)
    * 
* *

* That is, every key k is bound to a NEList of those elements x for which f(x) equals k. *

*/ def groupBy[K](f: T => K): Map[K, NEList[T]] = { val mapKToList = toList.groupBy(f) mapKToList.view.mapValues { list => new NEList(list) }.toMap } /** * Partitions elements into fixed size NELists. * * @param size the number of elements per group * @return An iterator producing NELists of size size, except the last will be truncated if the elements don't divide evenly. */ def grouped(size: Int): Iterator[NEList[T]] = { val itOfList = toList.grouped(size) itOfList.map { list => new NEList(list) } } /** * Returns true to indicate this NEList has a definite size, since all NELists are strict collections. */ def hasDefiniteSize: Boolean = true // override def hashCode: Int = toList.hashCode /** * Selects the first element of this NEList. * * @return the first element of this NEList. */ def head: T = toList.head def tail: List[T] = toList.tail /** * Finds index of first occurrence of some value in this NEList. * * @param elem the element value to search for. * @return the index of the first element of this NEList that is equal (as determined by ==) to elem, * or -1, if none exists. */ def indexOf[U >: T](elem: U): Int = toList.indexOf(elem, 0) /** * Finds index of first occurrence of some value in this NEList after or at some start index. * * @param elem the element value to search for. * @param from the start index * @return the index >= from of the first element of this NEList that is equal (as determined by ==) to elem, * or -1, if none exists. */ def indexOf[U >: T](elem: U, from: Int): Int = toList.indexOf(elem, from) /** * Finds first index where this NEList contains a given Seq as a slice. * * @param that the Seq defining the slice to look for * @return the first index at which the elements of this NEList starting at that index match the elements of * Seq that, or -1 of no such subsequence exists. */ def indexOfSlice[U >: T](that: Seq[U]): Int = toList.indexOfSlice(that) /** * Finds first index after or at a start index where this NEList contains a given Seq as a slice. * * @param that the Seq defining the slice to look for * @param from the start index * @return the first index >= from at which the elements of this NEList starting at that index match the elements of * Seq that, or -1 of no such subsequence exists. */ def indexOfSlice[U >: T](that: Seq[U], from: Int): Int = toList.indexOfSlice(that, from) /** * Finds first index where this NEList contains a given Vector as a slice. * * @param that the Vector defining the slice to look for * @return the first index such that the elements of this NEList starting at this index match the elements of * Vector that, or -1 of no such subsequence exists. */ def indexOfSlice[U >: T](that: Vector[U]): Int = toList.indexOfSlice(that) /** * Finds first index where this NEList contains a given NEList as a slice. * * @param that the NEList defining the slice to look for * @return the first index such that the elements of this NEList starting at this index match the elements of * NEList that, or -1 of no such subsequence exists. */ def indexOfSlice[U >: T](that: NEList[U]): Int = toList.indexOfSlice(that.toList) /** * Finds first index after or at a start index where this NEList contains a given Vector as a slice. * * @param that the Vector defining the slice to look for * @param from the start index * @return the first index >= from such that the elements of this NEList starting at this index match the elements of * Vector that, or -1 of no such subsequence exists. */ def indexOfSlice[U >: T](that: Vector[U], from: Int): Int = toList.indexOfSlice(that, from) /** * Finds first index after or at a start index where this NEList contains a given NEList as a slice. * * @param that the NEList defining the slice to look for * @param from the start index * @return the first index >= from such that the elements of this NEList starting at this index match the elements of * NEList that, or -1 of no such subsequence exists. */ def indexOfSlice[U >: T](that: NEList[U], from: Int): Int = toList.indexOfSlice(that.toList, from) /** * Finds index of the first element satisfying some predicate. * * @param p the predicate used to test elements. * @return the index of the first element of this NEList that satisfies the predicate p, * or -1, if none exists. */ def indexWhere(p: T => Boolean): Int = toList.indexWhere(p) /** * Finds index of the first element satisfying some predicate after or at some start index. * * @param p the predicate used to test elements. * @param from the start index * @return the index >= from of the first element of this NEList that satisfies the predicate p, * or -1, if none exists. */ def indexWhere(p: T => Boolean, from: Int): Int = toList.indexWhere(p, from) /** * Produces the range of all indices of this NEList. * * @return a Range value from 0 to one less than the length of this NEList. */ def indices: Range = toList.indices /** * Tests whether this NEList contains given index. * * @param idx the index to test * @return true if this NEList contains an element at position idx, false otherwise. */ def isDefinedAt(idx: Int): Boolean = toList.isDefinedAt(idx) /** * Returns false to indicate this NEList, like all NELists, is non-empty. * * @return false */ def isEmpty: Boolean = false /** * Returns true to indicate this NEList, like all NELists, can be traversed repeatedly. * * @return true */ def isTraversableAgain: Boolean = true /** * Creates and returns a new iterator over all elements contained in this NEList. * * @return the new iterator */ def iterator: Iterator[T] = toList.iterator /** * Selects the last element of this NEList. * * @return the last element of this NEList. */ def last: T = toList.last /** * Finds the index of the last occurrence of some value in this NEList. * * @param elem the element value to search for. * @return the index of the last element of this NEList that is equal (as determined by ==) to elem, * or -1, if none exists. */ def lastIndexOf[U >: T](elem: U): Int = toList.lastIndexOf(elem) /** * Finds the index of the last occurrence of some value in this NEList before or at a given end index. * * @param elem the element value to search for. * @param end the end index. * @return the index >= end of the last element of this NEList that is equal (as determined by ==) * to elem, or -1, if none exists. */ def lastIndexOf[U >: T](elem: U, end: Int): Int = toList.lastIndexOf(elem, end) /** * Finds the last index where this NEList contains a given Seq as a slice. * * @param that the Seq defining the slice to look for * @return the last index at which the elements of this NEList starting at that index match the elements of * Seq that, or -1 of no such subsequence exists. */ def lastIndexOfSlice[U >: T](that: Seq[U]): Int = toList.lastIndexOfSlice(that) /** * Finds the last index before or at a given end index where this NEList contains a given Seq as a slice. * * @param that the Seq defining the slice to look for * @param end the end index * @return the last index >= end at which the elements of this NEList starting at that index match the elements of * Seq that, or -1 of no such subsequence exists. */ def lastIndexOfSlice[U >: T](that: Seq[U], end: Int): Int = toList.lastIndexOfSlice(that, end) /** * Finds the last index where this NEList contains a given Vector as a slice. * * @param that the Vector defining the slice to look for * @return the last index at which the elements of this NEList starting at that index match the elements of * Vector that, or -1 of no such subsequence exists. */ def lastIndexOfSlice[U >: T](that: Vector[U]): Int = toList.lastIndexOfSlice(that) /** * Finds the last index where this NEList contains a given NEList as a slice. * * @param that the NEList defining the slice to look for * @return the last index at which the elements of this NEList starting at that index match the elements of * NEList that, or -1 of no such subsequence exists. */ def lastIndexOfSlice[U >: T](that: NEList[U]): Int = toList.lastIndexOfSlice(that.toList) /** * Finds the last index before or at a given end index where this NEList contains a given Vector as a slice. * * @param that the Vector defining the slice to look for * @param end the end index * @return the last index >= end at which the elements of this NEList starting at that index match the elements of * Vector that, or -1 of no such subsequence exists. */ def lastIndexOfSlice[U >: T](that: Vector[U], end: Int): Int = toList.lastIndexOfSlice(that, end) /** * Finds the last index before or at a given end index where this NEList contains a given NEList as a slice. * * @param that the NEList defining the slice to look for * @param end the end index * @return the last index >= end at which the elements of this NEList starting at that index match the elements of * NEList that, or -1 of no such subsequence exists. */ def lastIndexOfSlice[U >: T](that: NEList[U], end: Int): Int = toList.lastIndexOfSlice(that.toList, end) /** * Finds index of last element satisfying some predicate. * * @param p the predicate used to test elements. * @return the index of the last element of this NEList that satisfies the predicate p, or -1, if none exists. */ def lastIndexWhere(p: T => Boolean): Int = toList.lastIndexWhere(p) /** * Finds index of last element satisfying some predicate before or at given end index. * * @param p the predicate used to test elements. * @param end the end index * @return the index >= end of the last element of this NEList that satisfies the predicate p, * or -1, if none exists. */ def lastIndexWhere(p: T => Boolean, end: Int): Int = toList.lastIndexWhere(p, end) /** * The length of this NEList. * *

* @note length and size yield the same result, which will be >= 1. *

* * @return the number of elements in this NEList. */ def length: Int = toList.length /** * Compares the length of this NEList to a test value. * * @param len the test value that gets compared with the length. * @return a value x where * *
    * x < 0 if this.length < len
    * x == 0 if this.length == len
    * x > 0 if this.length > len
    * 
*/ def lengthCompare(len: Int): Int = toList.lengthCompare(len) /** * Builds a new NEList by applying a function to all elements of this NEList. * * @tparam U the element type of the returned NEList. * @param f the function to apply to each element. * @return a new NEList resulting from applying the given function f to each element of this NEList and collecting the results. */ def map[U](f: T => U): NEList[U] = new NEList(toList.map(f)) /** * Finds the largest element. * * @return the largest element of this NEList. */ def max[U >: T](implicit cmp: Ordering[U]): T = toList.max(cmp) /** * Finds the largest result after applying the given function to every element. * * @return the largest result of applying the given function to every element of this NEList. */ def maxBy[U](f: T => U)(implicit cmp: Ordering[U]): T = toList.maxBy(f)(cmp) /** * Finds the smallest element. * * @return the smallest element of this NEList. */ def min[U >: T](implicit cmp: Ordering[U]): T = toList.min(cmp) /** * Finds the smallest result after applying the given function to every element. * * @return the smallest result of applying the given function to every element of this NEList. */ def minBy[U](f: T => U)(implicit cmp: Ordering[U]): T = toList.minBy(f)(cmp) /** * Displays all elements of this NEList in a string. * * @return a string representation of this NEList. In the resulting string, the result of invoking toString on all elements of this * NEList follow each other without any separator string. */ def mkString: String = toList.mkString /** * Displays all elements of this NEList in a string using a separator string. * * @param sep the separator string * @return a string representation of this NEList. In the resulting string, the result of invoking toString on all elements of this * NEList are separated by the string sep. */ def mkString(sep: String): String = toList.mkString(sep) /** * Displays all elements of this NEList in a string using start, end, and separator strings. * * @param start the starting string. * @param sep the separator string. * @param end the ending string. * @return a string representation of this NEList. The resulting string begins with the string start and ends with the string * end. Inside, In the resulting string, the result of invoking toString on all elements of this NEList are * separated by the string sep. */ def mkString(start: String, sep: String, end: String): String = toList.mkString(start, sep, end) /** * Returns true to indicate this NEList, like all NELists, is non-empty. * * @return true */ def nonEmpty: Boolean = true /** * A copy of this NEList with an element value appended until a given target length is reached. * * @param len the target length * @param elem he padding value * @return a new NEList consisting of all elements of this NEList followed by the minimal number of occurrences * of elem so that the resulting NEList has a length of at least len. */ def padTo[U >: T](len: Int, elem: U): NEList[U] = new NEList(toList.padTo(len, elem)) /** * Produces a new NEList where a slice of elements in this NEList is replaced by another NEList * * @param from the index of the first replaced element * @param that the NEList whose elements should replace a slice in this NEList * @param replaced the number of elements to drop in the original NEList */ def patch[U >: T](from: Int, that: NEList[U], replaced: Int): NEList[U] = new NEList(toList.patch(from, that.toVector, replaced)) /** * Iterates over distinct permutations. * *

* Here's an example: *

* *
    * NEList('a', 'b', 'b').permutations.toList = List(NEList(a, b, b), NEList(b, a, b), NEList(b, b, a))
    * 
* * @return an iterator that traverses the distinct permutations of this NEList. */ def permutations: Iterator[NEList[T]] = { val it = toList.permutations it map { list => new NEList(list) } } /** * Returns the length of the longest prefix whose elements all satisfy some predicate. * * @param p the predicate used to test elements. * @return the length of the longest prefix of this NEList such that every element * of the segment satisfies the predicate p. */ def prefixLength(p: T => Boolean): Int = toList.segmentLength(p, 0) /** * The result of multiplying all the elements of this NEList. * *

* This method can be invoked for any NEList[T] for which an implicit Numeric[T] exists. *

* * @return the product of all elements */ def product[U >: T](implicit num: Numeric[U]): U = toList.product(num) /** * Reduces the elements of this NEList using the specified associative binary operator. * *

* The order in which operations are performed on elements is unspecified and may be nondeterministic. *

* * @tparam U a type parameter for the binary operator, a supertype of T. * @param op a binary operator that must be associative. * @return the result of applying reduce operator op between all the elements of this NEList. */ def reduce[U >: T](op: (U, U) => U): U = toList.reduce(op) /** * Applies a binary operator to all elements of this NEList, going left to right. * * @tparam U the result type of the binary operator. * @param op the binary operator. * @return the result of inserting op between consecutive elements of this NEList, going left to right: * *
    * op(...op(op(x_1, x_2), x_3), ..., x_n)
    * 
* *

* where x1, ..., xn are the elements of this NEList. *

*/ def reduceLeft[U >: T](op: (U, T) => U): U = toList.reduceLeft(op) /** * Applies a binary operator to all elements of this NEList, going left to right, returning the result in a Some. * * @tparam U the result type of the binary operator. * @param op the binary operator. * @return a Some containing the result of reduceLeft(op) *

*/ def reduceLeftOption[U >: T](op: (U, T) => U): Option[U] = toList.reduceLeftOption(op) def reduceOption[U >: T](op: (U, U) => U): Option[U] = toList.reduceOption(op) /** * Applies a binary operator to all elements of this NEList, going right to left. * * @tparam U the result of the binary operator * @param op the binary operator * @return the result of inserting op between consecutive elements of this NEList, going right to left: * *
    * op(x_1, op(x_2, ... op(x_{n-1}, x_n)...))
    * 
* *

* where x1, ..., xn are the elements of this NEList. *

*/ def reduceRight[U >: T](op: (T, U) => U): U = toList.reduceRight(op) /** * Applies a binary operator to all elements of this NEList, going right to left, returning the result in a Some. * * @tparam U the result of the binary operator * @param op the binary operator * @return a Some containing the result of reduceRight(op) */ def reduceRightOption[U >: T](op: (T, U) => U): Option[U] = toList.reduceRightOption(op) /** * Returns new NEList with elements in reverse order. * * @return a new NEList with all elements of this NEList in reversed order. */ def reverse: NEList[T] = new NEList(toList.reverse) /** * An iterator yielding elements in reverse order. * *

* @note NEList.reverseIterator is the same as NEList.reverse.iterator, but might be more efficient. *

* * @return an iterator yielding the elements of this NEList in reversed order */ def reverseIterator: Iterator[T] = toList.reverseIterator /** * Builds a new NEList by applying a function to all elements of this NEList and collecting the results in reverse order. * *

* @note NEList.reverseMap(f) is the same as NEList.reverse.map(f), but might be more efficient. *

* * @tparam U the element type of the returned NEList. * @param f the function to apply to each element. * @return a new NEList resulting from applying the given function f to each element of this NEList * and collecting the results in reverse order. */ def reverseMap[U](f: T => U): NEList[U] = new NEList(toList.reverseIterator.map(f).toList) /** * Checks if the given Iterable contains the same elements in the same order as this NEList. * * @param that the Iterable with which to compare * @return true, if both this NEList and the given Iterable contain the same elements * in the same order, false otherwise. */ def sameElements[U >: T](that: Iterable[U]): Boolean = toList.sameElements(that) /** * Checks if the given Vector contains the same elements in the same order as this NEList. * * @param that the Vector with which to compare * @return true, if both this and the given Vector contain the same elements * in the same order, false otherwise. */ def sameElements[U >: T](that: Vector[U]): Boolean = toList.sameElements(that) /** * Checks if the given NEList contains the same elements in the same order as this NEList. * * @param that the NEList with which to compare * @return true, if both this and the given NEList contain the same elements * in the same order, false otherwise. */ def sameElements[U >: T](that: NEList[U]): Boolean = toList.sameElements(that.toList) /** * Computes a prefix scan of the elements of this NEList. * *

* @note The neutral element z may be applied more than once. *

* *

* Here are some examples: *

* *
    * NEList(1, 2, 3).scan(0)(_ + _) == NEList(0, 1, 3, 6)
    * NEList(1, 2, 3).scan("z")(_ + _.toString) == NEList("z", "z1", "z12", "z123")
    * 
* * @tparam U a type parameter for the binary operator, a supertype of T, and the type of the resulting NEList. * @param z a neutral element for the scan operation; may be added to the result an arbitrary number of * times, and must not change the result (e.g., Nil for list concatenation, * 0 for addition, or 1 for multiplication.) * @param op a binary operator that must be associative * @return a new NEList containing the prefix scan of the elements in this NEList */ def scan[U >: T](z: U)(op: (U, U) => U): NEList[U] = new NEList(toList.scan(z)(op)) /** * Produces a NEList containing cumulative results of applying the operator going left to right. * *

* Here are some examples: *

* *
    * NEList(1, 2, 3).scanLeft(0)(_ + _) == NEList(0, 1, 3, 6)
    * NEList(1, 2, 3).scanLeft("z")(_ + _) == NEList("z", "z1", "z12", "z123")
    * 
* * @tparam B the result type of the binary operator and type of the resulting NEList * @param z the start value. * @param op the binary operator. * @return a new NEList containing the intermediate results of inserting op between consecutive elements of this NEList, * going left to right, with the start value, z, on the left. */ def scanLeft[B](z: B)(op: (B, T) => B): NEList[B] = new NEList(toList.scanLeft(z)(op)) /** * Produces a NEList containing cumulative results of applying the operator going right to left. * *

* Here are some examples: *

* *
    * NEList(1, 2, 3).scanRight(0)(_ + _) == NEList(6, 5, 3, 0)
    * NEList(1, 2, 3).scanRight("z")(_ + _) == NEList("123z", "23z", "3z", "z")
    * 
* * @tparam B the result of the binary operator and type of the resulting NEList * @param z the start value * @param op the binary operator * @return a new NEList containing the intermediate results of inserting op between consecutive elements of this NEList, * going right to left, with the start value, z, on the right. */ def scanRight[B](z: B)(op: (T, B) => B): NEList[B] = new NEList(toList.scanRight(z)(op)) /** * Computes length of longest segment whose elements all satisfy some predicate. * * @param p the predicate used to test elements. * @param from the index where the search starts. * @param the length of the longest segment of this NEList starting from index from such that every element of the * segment satisfies the predicate p. */ def segmentLength(p: T => Boolean, from: Int): Int = toList.segmentLength(p, from) /** * Groups elements in fixed size blocks by passing a “sliding window” over them (as opposed to partitioning them, as is done in grouped.) * * @param size the number of elements per group * @return an iterator producing NELists of size size, except the last and the only element will be truncated * if there are fewer elements than size. */ def sliding(size: Int): Iterator[NEList[T]] = toList.sliding(size).map(new NEList(_)) /** * Groups elements in fixed size blocks by passing a “sliding window” over them (as opposed to partitioning them, as is done in grouped.), * moving the sliding window by a given step each time. * * @param size the number of elements per group * @param step the distance between the first elements of successive groups * @return an iterator producing NELists of size size, except the last and the only element will be truncated * if there are fewer elements than size. */ def sliding(size: Int, step: Int): Iterator[NEList[T]] = toList.sliding(size, step).map(new NEList(_)) /** * The size of this NEList. * *

* @note length and size yield the same result, which will be >= 1. *

* * @return the number of elements in this NEList. */ def size: Int = toList.size /** * Sorts this NEList according to the Ordering of the result of applying the given function to every element. * * @tparam U the target type of the transformation f, and the type where the Ordering ord is defined. * @param f the transformation function mapping elements to some other domain U. * @param ord the ordering assumed on domain U. * @return a NEList consisting of the elements of this NEList sorted according to the Ordering where * x < y if ord.lt(f(x), f(y)). */ def sortBy[U](f: T => U)(implicit ord: Ordering[U]): NEList[T] = new NEList(toList.sortBy(f)) /** * Sorts this NEList according to a comparison function. * *

* The sort is stable. That is, elements that are equal (as determined by lt) appear in the same order in the * sorted NEList as in the original. *

* * @param the comparison function that tests whether its first argument precedes its second argument in the desired ordering. * @return a NEList consisting of the elements of this NEList sorted according to the comparison function lt. */ def sortWith(lt: (T, T) => Boolean): NEList[T] = new NEList(toList.sortWith(lt)) /** * Sorts this NEList according to an Ordering. * *

* The sort is stable. That is, elements that are equal (as determined by lt) appear in the same order in the * sorted NEList as in the original. *

* * @param ord the Ordering to be used to compare elements. * @param the comparison function that tests whether its first argument precedes its second argument in the desired ordering. * @return a NEList consisting of the elements of this NEList sorted according to the comparison function lt. */ def sorted[U >: T](implicit ord: Ordering[U]): NEList[U] = new NEList(toList.sorted(ord)) /** * Indicates whether this NEList starts with the given Seq. * * @param that the Seq slice to look for in this NEList * @return true if this NEList has that as a prefix, false otherwise. */ def startsWith[B](that: Seq[B]): Boolean = toList.startsWith[Any](that) /** * Indicates whether this NEList starts with the given Seq at the given index. * * @param that the Seq slice to look for in this NEList * @param offset the index at which this NEList is searched. * @return true if this NEList has that as a slice at the index offset, false otherwise. */ def startsWith[B](that: Seq[B], offset: Int): Boolean = toList.startsWith[Any](that, offset) /** * Indicates whether this NEList starts with the given Vector. * * @param that the Vector to test * @return true if this collection has that as a prefix, false otherwise. */ def startsWith[B](that: Vector[B]): Boolean = toList.startsWith[Any](that) /** * Indicates whether this NEList starts with the given NEList. * * @param that the NEList to test * @return true if this collection has that as a prefix, false otherwise. */ def startsWith[B](that: NEList[B]): Boolean = toList.startsWith[Any](that.toList) /** * Indicates whether this NEList starts with the given Vector at the given index. * * @param that the Vector slice to look for in this NEList * @param offset the index at which this NEList is searched. * @return true if this NEList has that as a slice at the index offset, false otherwise. */ def startsWith[B](that: Vector[B], offset: Int): Boolean = toList.startsWith[Any](that, offset) /** * Indicates whether this NEList starts with the given NEList at the given index. * * @param that the NEList slice to look for in this NEList * @param offset the index at which this NEList is searched. * @return true if this NEList has that as a slice at the index offset, false otherwise. */ def startsWith[B](that: NEList[B], offset: Int): Boolean = toList.startsWith[Any](that.toList, offset) /** * Returns "NEList", the prefix of this object's toString representation. * * @return the string "NEList" */ def stringPrefix: String = "NEList" /** * The result of summing all the elements of this NEList. * *

* This method can be invoked for any NEList[T] for which an implicit Numeric[T] exists. *

* * @return the sum of all elements */ def sum[U >: T](implicit num: Numeric[U]): U = toList.sum(num) // import scala.collection.compat._ /** * Converts this NEList into a collection of type Col by copying all elements. * * @tparam C1 the collection type to build. * @return a new collection containing all elements of this NEList. */ def to[C1](factory: Factory[T, C1]): C1 = factory.fromSpecific(iterator) /** * Converts this NEList to an array. * * @return an array containing all elements of this NEList. A ClassTag must be available for the element type of this NEList. */ def toArray[U >: T](implicit classTag: ClassTag[U]): Array[U] = toList.toArray /** * Converts this NEList to a Vector. * * @return a Vector containing all elements of this NEList. */ def toVector: Vector[T] = toList.toVector /** * Converts this NEList to a mutable buffer. * * @return a buffer containing all elements of this NEList. */ def toBuffer[U >: T]: mutable.Buffer[U] = toList.toBuffer /** * Converts this NEList to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all elements of this NEList. */ def toIndexedSeq: collection.immutable.IndexedSeq[T] = toList.toVector /** * Converts this NEList to an iterable collection. * * @return an Iterable containing all elements of this NEList. */ def toIterable: Iterable[T] = toList /** * Returns an Iterator over the elements in this NEList. * * @return an Iterator containing all elements of this NEList. */ def toIterator: Iterator[T] = toList.iterator /** * Converts this NEList to a list. * * @return a list containing all elements of this NEList. */ // def toList: List[T] = toList /** * Converts this NEList to a map. * *

* This method is unavailable unless the elements are members of Tuple2, each ((K, V)) becoming a key-value pair * in the map. Duplicate keys will be overwritten by later keys. *

* * @return a map of type immutable.Map[K, V] containing all key/value pairs of type (K, V) of this NEList. */ def toMap[K, V](implicit ev: T <:< (K, V)): Map[K, V] = toList.toMap /** * Converts this NEList to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all elements of this NEList. */ def toSeq: collection.immutable.Seq[T] = toList /** * Converts this NEList to a set. * * @return a set containing all elements of this NEList. */ def toSet[U >: T]: Set[U] = toList.toSet /** * Returns a string representation of this NEList. * * @return the string "NEList" followed by the result of invoking toString on * this NEList's elements, surrounded by parentheses. */ override def toString: String = "NEList(" + toList.mkString(", ") + ")" def transpose[U](implicit ev: T <:< NEList[U]): NEList[NEList[U]] = { val asLists = toList.map(ev) val list = asLists.map(_.toList).transpose new NEList(list.map(new NEList(_))) } /** * Produces a new NEList that contains all elements of this NEList and also all elements of a given Vector. * *

* NEListX union everyY is equivalent to NEListX ++ everyY. *

* *

* Another way to express this is that NEListX union everyY computes the order-presevring multi-set union * of NEListX and everyY. This union method is hence a counter-part of diff and intersect that * also work on multi-sets. *

* * @param that the Vector to add. * @return a new NEList that contains all elements of this NEList followed by all elements of that Vector. */ def union[U >: T](that: Vector[U]): NEList[U] = new NEList(toList ++ that) /** * Produces a new NEList that contains all elements of this NEList and also all elements of a given NEList. * *

* NEListX union NEListY is equivalent to NEListX ++ NEListY. *

* *

* Another way to express this is that NEListX union NEListY computes the order-presevring multi-set union * of NEListX and NEListY. This union method is hence a counter-part of diff and intersect that * also work on multi-sets. *

* * @param that the NEList to add. * @return a new NEList that contains all elements of this NEList followed by all elements of that. */ def union[U >: T](that: NEList[U]): NEList[U] = new NEList(toList ++ that.toList) /** * Produces a new NEList that contains all elements of this NEList and also all elements of a given Seq. * *

* NEListX union ys is equivalent to NEListX ++ ys. *

* *

* Another way to express this is that NEListX union ys computes the order-presevring multi-set union * of NEListX and ys. This union method is hence a counter-part of diff and intersect that * also work on multi-sets. *

* * @param that the Seq to add. * @return a new NEList that contains all elements of this NEList followed by all elements of that Seq. */ def union[U >: T](that: Seq[U]): NEList[U] = new NEList(toList ++ that) /** * Converts this NEList of pairs into two NELists of the first and second half of each pair. * * @tparam L the type of the first half of the element pairs * @tparam R the type of the second half of the element pairs * @param asPair an implicit conversion that asserts that the element type of this NEList is a pair. * @return a pair of NELists, containing the first and second half, respectively, of each element pair of this NEList. */ def unzip[L, R](implicit asPair: T => (L, R)): (NEList[L], NEList[R]) = { val unzipped = toList.unzip (new NEList(unzipped._1), new NEList(unzipped._2)) } /** * Converts this NEList of triples into three NELists of the first, second, and and third element of each triple. * * @tparam L the type of the first member of the element triples * @tparam R the type of the second member of the element triples * @tparam R the type of the third member of the element triples * @param asTriple an implicit conversion that asserts that the element type of this NEList is a triple. * @return a triple of NELists, containing the first, second, and third member, respectively, of each element triple of this NEList. */ def unzip3[L, M, R](implicit asTriple: T => (L, M, R)): (NEList[L], NEList[M], NEList[R]) = { val unzipped = toList.unzip3 (new NEList(unzipped._1), new NEList(unzipped._2), new NEList(unzipped._3)) } /** * A copy of this NEList with one single replaced element. * * @param idx the position of the replacement * @param elem the replacing element * @throws IndexOutOfBoundsException if the passed index is greater than or equal to the length of this NEList * @return a copy of this NEList with the element at position idx replaced by elem. */ def updated[U >: T](idx: Int, elem: U): NEList[U] = try new NEList(toList.updated(idx, elem)) catch { case _: UnsupportedOperationException => throw new IndexOutOfBoundsException(idx.toString) } // This is needed for 2.10 support. Can drop after. // Because 2.11 throws IndexOutOfBoundsException. /** * Returns a NEList formed from this NEList and an iterable collection by combining corresponding * elements in pairs. If one of the two collections is shorter than the other, placeholder elements will be used to extend the * shorter collection to the length of the longer. * * @tparm O the type of the second half of the returned pairs * @tparm U the type of the first half of the returned pairs * @param other the Iterable providing the second half of each result pair * @param thisElem the element to be used to fill up the result if this NEList is shorter than that Iterable. * @param thatElem the element to be used to fill up the result if that Iterable is shorter than this NEList. * @return a new NEList containing pairs consisting of corresponding elements of this NEList and that. The * length of the returned collection is the maximum of the lengths of this NEList and that. If this NEList * is shorter than that, thisElem values are used to pad the result. If that is shorter than this * NEList, thatElem values are used to pad the result. */ def zipAll[O, U >: T](other: collection.Iterable[O], thisElem: U, otherElem: O): NEList[(U, O)] = new NEList(toList.zipAll(other, thisElem, otherElem)) /** * Zips this NEList with its indices. * * @return A new NEList containing pairs consisting of all elements of this NEList paired with their index. Indices start at 0. */ def zipWithIndex: NEList[(T, Int)] = new NEList(toList.zipWithIndex) } /** * Companion object for class NEList. */ object NEList extends NEListInstances { /** * Constructs a new NEList of one element */ @inline def apply[T](singleElement: T): NEList[T] = new NEList[T](singleElement :: Nil) /** * Constructs a new NEList given at least two elements. * * @tparam T the type of the element contained in the new NEList * @param firstElement the first element (with index 0) contained in this NEList * @param otherElements a varargs of zero or more other elements (with index 1, 2, 3, ...) contained in this NEList */ @inline def apply[T](firstElement: T, secondElement: T, otherElements: T*): NEList[T] = new NEList(firstElement :: secondElement :: otherElements.toList) /** * Constructs a new NEList given at least one element. */ @inline def apply[T](firstElement: T, otherElements: Iterable[T]): NEList[T] = new NEList(firstElement :: otherElements.toList) /** * Variable argument extractor for NELists. * * @param NEList: the NEList containing the elements to extract * @return an Seq containing this NELists elements, wrapped in a Some */ @inline def unapplySeq[T](NEList: NEList[T]): Some[Seq[T]] = Some(NEList.toList) /** * Optionally construct a NEList containing the elements, if any, of a given List. * * @param list the List with which to construct a NEList * @return a NEList containing the elements of the given List, if non-empty, wrapped in * a Some; else None if the List is empty */ @inline def from[T](list: List[T]): Option[NEList[T]] = { if (list.isEmpty) None else Some(new NEList(list)) } /** * Optionally construct a NEList containing the elements, if any, of a given Seq. * * @param seq the Seq with which to construct a NEList * @return a NEList containing the elements of the given Seq, if non-empty, wrapped in * a Some; else None if the Seq is empty */ @inline def from[T](seq: Iterable[T]): Option[NEList[T]] = { from(seq.toList) } @inline def from[T](iterableOnce: IterableOnce[T]): Option[NEList[T]] = { from(iterableOnce.iterator.toList) } @inline def unsafeFrom[T](list: List[T]): NEList[T] = { require(list.nonEmpty) new NEList(list) } @inline implicit def asIterable[A](nel: NEList[A]): IterableOnce[A] = nel.toIterable implicit final class OptionOps[+A](private val option: Option[NEList[A]]) extends AnyVal { @inline def fromNEList: List[A] = if (option.isEmpty) Nil else option.get.toList } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy