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

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

package izumi.fundamentals.collections.nonempty

// shameless copypaste from Scalactic

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

// Can't be a LinearSeq[T] because Builder would be able to create an empty one.
/**
  * A non-empty Set: an ordered, immutable, non-empty collection of elements with LinearSeq performance characteristics.
  *
  * 

* The purpose of NESet is to allow you to express in a type that a Set is non-empty, thereby eliminating the * need for (and potential exception from) a run-time check for non-emptiness. For a non-empty sequence with IndexedSeq * performance, see Vector. *

* *

Constructing NESets

* *

* You can construct a NESet by passing one or more elements to the NESet.apply factory method: *

* *
  * scala> NESet(1, 2, 3)
  * res0: org.scalactic.anyvals.NESet[Int] = NESet(1, 2, 3)
  * 
* *

* Alternatively you can cons elements onto the End singleton object, similar to making a Set starting with Nil: *

* *
  * scala> 1 :: 2 :: 3 :: Nil
  * res0: Set[Int] = Set(1, 2, 3)
  *
  * scala> 1 :: 2 :: 3 :: End
  * res1: org.scalactic.NESet[Int] = NESet(1, 2, 3)
  * 
* *

* Note that although Nil is a Set[Nothing], End is * not a NESet[Nothing], because no empty NESet exists. (A non-empty Set is a series * of connected links; if you have no links, you have no non-empty Set.) *

* *
  * scala> val nil: Set[Nothing] = Nil
  * nil: Set[Nothing] = Set()
  *
  * scala> val nada: NESet[Nothing] = End
  * <console>:16: error: type mismatch;
  * found   : org.scalactic.anyvals.End.type
  * required: org.scalactic.anyvals.NESet[Nothing]
  *        val nada: NESet[Nothing] = End
  *                                          ^
  * 
* *

Working with NESets

* *

* NESet does not extend Scala's Seq or Traversable traits because these require that * implementations may be empty. For example, if you invoke tail on a Seq that contains just one element, * you'll get an empty Seq: *

* *
  * scala> Set(1).tail
  * res6: Set[Int] = Set()
  * 
* *

* On the other hand, many useful methods exist on Seq that when invoked on a non-empty Seq are guaranteed * to not result in an empty Seq. For convenience, NESet defines a method corresponding to every such Seq * method. Here are some examples: *

* *
  * NESet(1, 2, 3).map(_ + 1)                        // Result: NESet(2, 3, 4)
  * NESet(1).map(_ + 1)                              // Result: NESet(2)
  * NESet(1, 2, 3).containsSlice(NESet(2, 3)) // Result: true
  * NESet(1, 2, 3).containsSlice(NESet(3, 4)) // Result: false
  * NESet(-1, -2, 3, 4, 5).minBy(_.abs)              // Result: -1
  * 
* *

* NESet does not currently define any methods corresponding to Seq methods that could result in * an empty Seq. However, an implicit converison from NESet to Set * is defined in the NESet companion object that will be applied if you attempt to call one of the missing methods. As a * result, you can invoke filter on an NESet, even though filter could result * in an empty sequence—but the result type will be Set instead of NESet: *

* *
  * NESet(1, 2, 3).filter(_ < 10) // Result: Set(1, 2, 3)
  * NESet(1, 2, 3).filter(_ > 10) // Result: Set()
  * 
* *

* You can use NESets in for expressions. The result will be an NESet unless * you use a filter (an if clause). Because filters are desugared to invocations of filter, the * result type will switch to a Set at that point. Here are some examples: *

* *
  * scala> import org.scalactic.anyvals._
  * import org.scalactic.anyvals._
  *
  * scala> for (i <- NESet(1, 2, 3)) yield i + 1
  * res0: org.scalactic.anyvals.NESet[Int] = NESet(2, 3, 4)
  *
  * scala> for (i <- NESet(1, 2, 3) if i < 10) yield i + 1
  * res1: Set[Int] = Set(2, 3, 4)
  *
  * scala> for {
  *      |   i <- NESet(1, 2, 3)
  *      |   j <- NESet('a', 'b', 'c')
  *      | } yield (i, j)
  * res3: org.scalactic.anyvals.NESet[(Int, Char)] =
  *         NESet((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c))
  *
  * scala> for {
  *      |   i <- NESet(1, 2, 3) if i < 10
  *      |   j <- NESet('a', 'b', 'c')
  *      | } yield (i, j)
  * res6: Set[(Int, Char)] =
  *         Set((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), (3,a), (3,b), (3,c))
  * 
* * @tparam T the type of elements contained in this NESet */ final class NESet[T] private (val toSet: Set[T]) extends AnyVal { /** * Returns a new NESet containing the elements of this NESet followed by the elements of the passed NESet. * The element type of the resulting NESet is the most specific superclass encompassing the element types of this and the passed NESet. * * @tparam U the element type of the returned NESet * @param other the NESet to append * @return a new NESet that contains all the elements of this NESet followed by all elements of other. */ def ++[U >: T](other: NESet[U]): NESet[U] = new NESet(toSet ++ other.toSet) /** * Returns a new NESet containing the elements of this NESet followed by the elements of the passed Vector. * The element type of the resulting NESet is the most specific superclass encompassing the element types of this NESet and the passed Vector. * * @tparam U the element type of the returned NESet * @param other the Vector to append * @return a new NESet that contains all the elements of this NESet followed by all elements of other. */ def ++[U >: T](other: Vector[U]): NESet[U] = new NESet(toSet ++ other) // TODO: Have I added these extra ++, etc. methods to Vector that take a NESet? /** * Returns a new NESet containing the elements of this NESet followed by the elements of the passed GenTraversableOnce. * The element type of the resulting NESet is the most specific superclass encompassing the element types of this NESet * and the passed GenTraversableOnce. * * @param other the GenTraversableOnce to append * @return a new NESet that contains all the elements of this NESet followed by all elements of other. */ def ++(other: IterableOnce[T]): NESet[T] = if (other.iterator.isEmpty) this else new NESet(toSet ++ other.iterator.to(Set)) /** * Returns a new NESet with the given element added. * * @param element the element to add to this NESet * @return a new NESet consisting of element and all elements of this NESet. */ def +(element: T): NESet[T] = new NESet(toSet ++ Set(element)) /** * Appends all elements of this NESet to a string builder. The written text will consist of a concatenation of the result of invoking toString * on of every element of this NESet, 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 = toSet.addString(sb) /** * Check if an element exists at its index in the NESet. * * @return true if a element exists in NESet at index idx, where false indicates the element at index idx does not exist. */ def apply(elem: T): Boolean = toSet(elem) /** * Appends all elements of this NESet 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 NESet, 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 = toSet.addString(sb, sep) /** * Appends all elements of this NESet 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 NESet, * 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 = toSet.addString(sb, start, sep, end) /** * Finds the first element of this NESet 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] = toSet.collectFirst(pf) /** * Indicates whether this NESet contains a given value as an element. * * @param elem the element to look for * @return true if this NESet has an element that is equal (as determined by ==) to elem, false otherwise. */ infix def contains(elem: T): Boolean = toSet.contains(elem) /** * Copies values of this NESet to an array. Fills the given array arr with values of this NESet. Copying * will stop once either the end of the current NESet is reached, or the end of the array is reached. * * @param arr the array to fill */ def copyToArray[U >: T](arr: Array[U]): Unit = { toSet.copyToArray(arr) () } /** * Copies values of this NESet to an array. Fills the given array arr with values of this NESet, beginning at * index start. Copying will stop once either the end of the current NESet 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 = { toSet.copyToArray(arr, start) () } /** * Copies values of this NESet to an array. Fills the given array arr with at most len elements of this NESet, beginning at * index start. Copying will stop once either the end of the current NESet 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 = { toSet.copyToArray(arr, start, len) () } /** * Copies all elements of this NESet to a buffer. * * @param buf the buffer to which elements are copied */ def copyToBuffer[U >: T](buf: Buffer[U]): Unit = { buf ++= toSet () } /** * Counts the number of elements in this NESet 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 = toSet.count(p) /** * Indicates whether a predicate holds for at least one of the elements of this NESet. * * @param p the predicate used to test elements. * @return true if the given predicate p holds for some of the elements of this NESet, otherwise false. */ def exists(p: T => Boolean): Boolean = toSet.exists(p) /** * Finds the first element of this NESet that satisfies the given predicate, if any. * * @param p the predicate used to test elements * @return an Some containing the first element in this NESet that satisfies p, or None if none exists. */ def find(p: T => Boolean): Option[T] = toSet.find(p) /** * Builds a new NESet by applying a function to all elements of this NESet and using the elements of the resulting NESets. * * @tparam U the element type of the returned NESet * @param f the function to apply to each element. * @return a new NESet containing elements obtained by applying the given function f to each element of this NESet and concatenating * the elements of resulting NESets. */ def flatMap[U](f: T => NESet[U]): NESet[U] = { val buf = new ArrayBuffer[U] for (ele <- toSet) buf ++= f(ele).toSet new NESet(buf.toSet) } /** * Converts this NESet of NESets into a NESet * formed by the elements of the nested NESets. * *

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

* * @tparm B the type of the elements of each nested NESet * @return a new NESet resulting from concatenating all nested NESets. */ def flatten[B](implicit ev: T <:< NESet[B]): NESet[B] = flatMap(ev) /** * Folds the elements of this NESet 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 Set 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 = toSet.fold(z)(op) /** * Applies a binary operator to a start value and all elements of this NESet, 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 NESet, 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 NESet. *

*/ def foldLeft[B](z: B)(op: (B, T) => B): B = toSet.foldLeft(z)(op) /** * Applies a binary operator to all elements of this NESet 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 NESet, 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 NESet. *

*/ def foldRight[B](z: B)(op: (T, B) => B): B = toSet.foldRight(z)(op) /** * Indicates whether a predicate holds for all elements of this NESet. * * @param p the predicate used to test elements. * @return true if the given predicate p holds for all elements of this NESet, otherwise false. */ def forall(p: T => Boolean): Boolean = toSet.forall(p) /** * Applies a function f to all elements of this NESet. * * @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 = toSet.foreach(f) /** * Partitions this NESet into a map of NESets 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 NESets such that the following invariant holds: * *
    * (NESet.toSet partition f)(k) = xs filter (x => f(x) == k)
    * 
* *

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

*/ def groupBy[K](f: T => K): Map[K, NESet[T]] = { val mapKToSet = toSet.groupBy(f) mapKToSet.view.mapValues { Set => new NESet(Set) }.toMap } /** * Partitions elements into fixed size NESets. * * @param size the number of elements per group * @return An iterator producing NESets of size size, except the last will be truncated if the elements don't divide evenly. */ def grouped(size: Int): Iterator[NESet[T]] = { val itOfSet = toSet.grouped(size) itOfSet.map { Set => new NESet(Set) } } /** * Returns true to indicate this NESet has a definite size, since all NESets are strict collections. */ def hasDefiniteSize: Boolean = true // override def hashCode: Int = toSet.hashCode /** * Selects the first element of this NESet. * * @return the first element of this NESet. */ def head: T = toSet.head def tail: Set[T] = toSet.tail /** * Returns false to indicate this NESet, like all NESets, is non-empty. * * @return false */ def isEmpty: Boolean = false /** * Returns true to indicate this NESet, like all NESets, can be traversed repeatedly. * * @return true */ def isTraversableAgain: Boolean = true /** * Creates and returns a new iterator over all elements contained in this NESet. * * @return the new iterator */ def iterator: Iterator[T] = toSet.iterator /** * Selects the last element of this NESet. * * @return the last element of this NESet. */ def last: T = toSet.last /** * Builds a new NESet by applying a function to all elements of this NESet. * * @tparam U the element type of the returned NESet. * @param f the function to apply to each element. * @return a new NESet resulting from applying the given function f to each element of this NESet and collecting the results. */ def map[U](f: T => U): NESet[U] = new NESet(toSet.map(f)) /** * Finds the largest element. * * @return the largest element of this NESet. */ def max[U >: T](implicit cmp: Ordering[U]): T = toSet.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 NESet. */ def maxBy[U](f: T => U)(implicit cmp: Ordering[U]): T = toSet.maxBy(f)(cmp) /** * Finds the smallest element. * * @return the smallest element of this NESet. */ def min[U >: T](implicit cmp: Ordering[U]): T = toSet.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 NESet. */ def minBy[U](f: T => U)(implicit cmp: Ordering[U]): T = toSet.minBy(f)(cmp) /** * Displays all elements of this NESet in a string. * * @return a string representation of this NESet. In the resulting string, the result of invoking toString on all elements of this * NESet follow each other without any separator string. */ def mkString: String = toSet.mkString /** * Displays all elements of this NESet in a string using a separator string. * * @param sep the separator string * @return a string representation of this NESet. In the resulting string, the result of invoking toString on all elements of this * NESet are separated by the string sep. */ def mkString(sep: String): String = toSet.mkString(sep) /** * Displays all elements of this NESet 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 NESet. 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 NESet are * separated by the string sep. */ def mkString(start: String, sep: String, end: String): String = toSet.mkString(start, sep, end) /** * Returns true to indicate this NESet, like all NESets, is non-empty. * * @return true */ def nonEmpty: Boolean = true /** * The result of multiplying all the elements of this NESet. * *

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

* * @return the product of all elements */ def product[U >: T](implicit num: Numeric[U]): U = toSet.product(num) /** * Reduces the elements of this NESet 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 NESet. */ def reduce[U >: T](op: (U, U) => U): U = toSet.reduce(op) /** * Applies a binary operator to all elements of this NESet, 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 NESet, going left to right: * *
    * op(...op(op(x_1, x_2), x_3), ..., x_n)
    * 
* *

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

*/ def reduceLeft[U >: T](op: (U, T) => U): U = toSet.reduceLeft(op) /** * Applies a binary operator to all elements of this NESet, 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] = toSet.reduceLeftOption(op) def reduceOption[U >: T](op: (U, U) => U): Option[U] = toSet.reduceOption(op) /** * Applies a binary operator to all elements of this NESet, 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 NESet, going right to left: * *
    * op(x_1, op(x_2, ... op(x_{n-1}, x_n)...))
    * 
* *

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

*/ def reduceRight[U >: T](op: (T, U) => U): U = toSet.reduceRight(op) /** * Applies a binary operator to all elements of this NESet, 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] = toSet.reduceRightOption(op) /** * Checks if the given Iterable contains the same elements in the same order as this NESet. * * @param that the Iterable with which to compare * @return true, if both this NESet and the given Iterable contain the same elements * in the same order, false otherwise. */ def sameElements[U >: T](that: Iterable[U]): Boolean = toSet == that.toSet /** * Checks if the given Vector contains the same elements in the same order as this NESet. * * @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 = toSet == that.toSet /** * Checks if the given NESet contains the same elements in the same order as this NESet. * * @param that the NESet with which to compare * @return true, if both this and the given NESet contain the same elements * in the same order, false otherwise. */ def sameElements[U >: T](that: NESet[U]): Boolean = toSet == that.toSet /** * Computes a prefix scan of the elements of this NESet. * *

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

* *

* Here are some examples: *

* *
    * NESet(1, 2, 3).scan(0)(_ + _) == NESet(0, 1, 3, 6)
    * NESet(1, 2, 3).scan("z")(_ + _.toString) == NESet("z", "z1", "z12", "z123")
    * 
* * @tparam U a type parameter for the binary operator, a supertype of T, and the type of the resulting NESet. * @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 Set concatenation, * 0 for addition, or 1 for multiplication.) * @param op a binary operator that must be associative * @return a new NESet containing the prefix scan of the elements in this NESet */ def scan[U >: T](z: U)(op: (U, U) => U): NESet[U] = new NESet(toSet.scan(z)(op)) /** * Produces a NESet containing cumulative results of applying the operator going left to right. * *

* Here are some examples: *

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

* Here are some examples: *

* *
    * NESet(1, 2, 3).scanRight(0)(_ + _) == NESet(6, 5, 3, 0)
    * NESet(1, 2, 3).scanRight("z")(_ + _) == NESet("123z", "23z", "3z", "z")
    * 
* * @tparam B the result of the binary operator and type of the resulting NESet * @param z the start value * @param op the binary operator * @return a new NESet containing the intermediate results of inserting op between consecutive elements of this NESet, * going right to left, with the start value, z, on the right. */ def scanRight[B](z: B)(op: (T, B) => B): NESet[B] = new NESet(toSet.scanRight(z)(op)) /** * 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 NESets 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[NESet[T]] = toSet.sliding(size).map(new NESet(_)) /** * 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 NESets 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[NESet[T]] = toSet.sliding(size, step).map(new NESet(_)) /** * The size of this NESet. * *

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

* * @return the number of elements in this NESet. */ def size: Int = toSet.size /** * Returns "NESet", the prefix of this object's toString representation. * * @return the string "NESet" */ def stringPrefix: String = "NESet" infix def subsetOf(that: Set[T]): Boolean = toSet.subsetOf(that) /** * The result of summing all the elements of this NESet. * *

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

* * @return the sum of all elements */ def sum[U >: T](implicit num: Numeric[U]): U = toSet.sum(num) /** * Converts this NESet 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 NESet. */ def to[C1](factory: Factory[T, C1]): C1 = factory.fromSpecific(iterator) /** * Converts this NESet to an array. * * @return an array containing all elements of this NESet. A ClassTag must be available for the element type of this NESet. */ def toArray[U >: T](implicit classTag: ClassTag[U]): Array[U] = toSet.toArray /** * Converts this NESet to a Vector. * * @return a Vector containing all elements of this NESet. */ def toVector: Vector[T] = toSet.toVector /** * Converts this NESet to a mutable buffer. * * @return a buffer containing all elements of this NESet. */ def toBuffer[U >: T]: Buffer[U] = toSet.toBuffer /** * Converts this NESet to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all elements of this NESet. */ def toIndexedSeq: scala.collection.immutable.IndexedSeq[T] = toSet.toVector /** * Converts this NESet to an iterable collection. * * @return an Iterable containing all elements of this NESet. */ def toIterable: Iterable[T] = toSet /** * Returns an Iterator over the elements in this NESet. * * @return an Iterator containing all elements of this NESet. */ def toIterator: Iterator[T] = toSet.iterator /** * Converts this NESet to a Set. * * @return a Set containing all elements of this NESet. */ // def toSet: Set[T] = toSet /** * Converts this NESet 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 NESet. */ def toMap[K, V](implicit ev: T <:< (K, V)): Map[K, V] = toSet.toMap /** * Converts this NESet to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all elements of this NESet. */ def toSeq: Seq[T] = toSet.toSeq /** * Converts this NESet to a set. * * @return a set containing all elements of this NESet. */ def toList: scala.collection.immutable.List[T] = toSet.toList /** * Returns a string representation of this NESet. * * @return the string "NESet" followed by the result of invoking toString on * this NESet's elements, surrounded by parentheses. */ override def toString: String = "NESet(" + toSet.mkString(", ") + ")" def transpose[U](implicit ev: T <:< NESet[U]): NESet[NESet[U]] = { val asSets = toSet.map(ev) val Set = asSets.map(_.toSet).transpose new NESet(Set.map(new NESet(_))) } /** * Produces a new NESet that contains all elements of this NESet and also all elements of a given Vector. * *

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

* *

* Another way to express this is that NESetX union everyY computes the order-presevring multi-set union * of NESetX 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 NESet that contains all elements of this NESet followed by all elements of that Vector. */ infix def union(that: Vector[T]): NESet[T] = new NESet(toSet union that.toSet) /** * Produces a new NESet that contains all elements of this NESet and also all elements of a given NESet. * *

* NESetX union NESetY is equivalent to NESetX ++ NESetY. *

* *

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

* * @param that the NESet to add. * @return a new NESet that contains all elements of this NESet followed by all elements of that. */ infix def union(that: NESet[T]): NESet[T] = new NESet(toSet union that.toSet) /** * Produces a new NESet that contains all elements of this NESet and also all elements of a given GenSeq. * *

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

* *

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

* * @param that the Set to add. * @return a new NESet that contains all elements of this NESet followed by all elements of that GenSeq. */ infix def union(that: Set[T])(implicit dummyImplicit: DummyImplicit): NESet[T] = new NESet(toSet.union(that)) /** * Converts this NESet of pairs into two NESets 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 NESet is a pair. * @return a pair of NESets, containing the first and second half, respectively, of each element pair of this NESet. */ def unzip[L, R](implicit asPair: T => (L, R)): (NESet[L], NESet[R]) = { val unzipped = toSet.unzip (new NESet(unzipped._1), new NESet(unzipped._2)) } /** * Converts this NESet of triples into three NESets of the first, second, and and third element of each triple. * * @tparam L the type of the first member of the element triples * @tparam M 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 NESet is a triple. * @return a triple of NESets, containing the first, second, and third member, respectively, of each element triple of this NESet. */ def unzip3[L, M, R](implicit asTriple: T => (L, M, R)): (NESet[L], NESet[M], NESet[R]) = { val unzipped = toSet.unzip3 (new NESet(unzipped._1), new NESet(unzipped._2), new NESet(unzipped._3)) } /** * Returns a NESet formed from this NESet 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 NESet is shorter than that Iterable. * @param otherElem the element to be used to fill up the result if that Iterable is shorter than this NESet. * @return a new NESet containing pairs consisting of corresponding elements of this NESet and that. The * length of the returned collection is the maximum of the lengths of this NESet and that. If this NESet * is shorter than that, thisElem values are used to pad the result. If that is shorter than this * NESet, thatElem values are used to pad the result. */ def zipAll[O, U >: T](other: collection.Iterable[O], thisElem: U, otherElem: O): NESet[(U, O)] = new NESet(toSet.zipAll(other, thisElem, otherElem)) /** * Zips this NESet with its indices. * * @return A new NESet containing pairs consisting of all elements of this NESet paired with their index. Indices start at 0. */ def zipWithIndex: NESet[(T, Int)] = new NESet(toSet.zipWithIndex) def widen[U >: T]: NESet[U] = new NESet(toSet.toSet[U]) } /** * Companion object for class NESet. */ object NESet extends NESetInstances { /** * Constructs a new NESet given at least one element. * * @tparam T the type of the element contained in the new NESet * @param firstElement the first element (with index 0) contained in this NESet * @param otherElements a varargs of zero or more other elements (with index 1, 2, 3, ...) contained in this NESet */ @inline def apply[T](firstElement: T, otherElements: T*): NESet[T] = new NESet(otherElements.toSet + firstElement) /** * Variable argument extractor for NESets. * * @param NESet: the NESet containing the elements to extract * @return an Seq containing this NESets elements, wrapped in a Some */ @inline def unapplySeq[T](NESet: NESet[T]): Some[Seq[T]] = Some(NESet.toSeq) /** * Optionally construct a NESet containing the elements, if any, of a given Set. * * @param set the Set with which to construct a NESet * @return a NESet containing the elements of the given GenSeq, if non-empty, wrapped in * a Some; else None if the GenSeq is empty */ @inline def from[T](set: scala.collection.immutable.Set[T]): Option[NESet[T]] = set.headOption match { case None => None case Some(_) => Some(new NESet(set)) } @inline def unsafeFrom[T](set: scala.collection.immutable.Set[T]): NESet[T] = { require(set.nonEmpty) new NESet(set) } implicit final class OptionOps[A](private val option: Option[NESet[A]]) extends AnyVal { @inline def fromNESet: Set[A] = if (option.isEmpty) Set.empty else option.get.toSet } @inline implicit def asIterable[A](ne: NESet[A]): IterableOnce[A] = ne.toIterable }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy