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

org.scalactic.anyvals.NonEmptyMap.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2001-2013 Artima, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.scalactic.anyvals

import scala.annotation.unchecked.{ uncheckedVariance => uV }
import scala.collection.GenIterable
import scala.collection.GenSeq
import scala.collection.GenTraversableOnce
import scala.collection.generic.CanBuildFrom
import scala.collection.mutable.Buffer
import scala.reflect.ClassTag
import scala.collection.immutable
import scala.collection.mutable.ArrayBuffer
import org.scalactic.Every


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

* The purpose of NonEmptyMap is to allow you to express in a type that a Map 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 Every. *

* *

Constructing NonEmptyMaps

* *

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

* *
  * scala> NonEmptyMap(1 -> "one", 2 -> "two", 3 -> "three")
  * res0: org.scalactic.anyvals.NonEmptyMap[Int, String] = NonEmptyMap(1 -> "one", 2 -> "two", 3 -> "three")
  * 
* *

Working with NonEmptyMaps

* *

* NonEmptyMap does not extend Scala's Map 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> Map(1 -> "one").tail
  * res6: Map[Int] = Map()
  * 
* *

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

* *
  * NonEmptyMap(1 -> "one", 2 -> "two", 3 -> "three").map(t => (t._1 + 1, t._2))                        // Result: NonEmptyMap(2 -> "one", 3 -> "two", 4 -> "three")
  * 
* *

* NonEmptyMap does not currently define any methods corresponding to Map methods that could result in * an empty Map. However, an implicit converison from NonEmptyMap to Map * is defined in the NonEmptyMap 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 NonEmptyMap, even though filter could result * in an empty map—but the result type will be Map instead of NonEmptyMap: *

* *
  * NonEmptyMap(1 -> "one", 2 -> "two", 3 -> "three").filter(_._1 < 10) // Result: Map(1 -> "one", 2 -> "two", 3 -> "three")
  * NonEmptyMap(1 -> "one", 2 -> "two", 3 -> "three").filter(_._ 1> 10) // Result: Map()
  * 
* * *

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

* *
  * scala> import org.scalactic.anyvals._
  * import org.scalactic.anyvals._
  *
  * scala> for ((i, j) <- NonEmptyMap(1 -> "one", 2 -> "two", 3 -> "three")) yield (i + 1, j)
  * res0: org.scalactic.anyvals.NonEmptyMap[Int, String] = NonEmptyMap(2 -> "one", 3 -> "two", 4 -> "three")
  *
  * scala> for ((i, j) <- NonEmptyMap(1, 2, 3) if i < 10) yield (i + 1, j)
  * res1: Map[Int, String] = Map(2 -> "one", 3 -> "two", 4 -> "three")
  * 
* * @tparam K the type of key contained in this NonEmptyMap * @tparam V the type of value contained in this NonEmptyMap */ final class NonEmptyMap[K, +V] private (val toMap: Map[K, V]) extends AnyVal { /** * Returns a new NonEmptyMap containing the entries of this NonEmptyMap and the entries of the passed NonEmptyMap. * The entry type of the resulting NonEmptyMap is the most specific superclass encompassing the entry types of this and the passed NonEmptyMap. * * @tparam V1 the value type of the returned NonEmptyMap * @param other the NonEmptyMap to append * @return a new NonEmptyMap that contains all the elements of this NonEmptyMap and all elements of other. */ def ++[V1 >: V](other: NonEmptyMap[K, V1]): NonEmptyMap[K, V1] = new NonEmptyMap(toMap ++ other.toMap) /** * Returns a new NonEmptyMap containing the entries of this NonEmptyMap and the entries of the passed Every. * The entry type of the resulting NonEmptyMap is the most specific superclass encompassing the entry types of this NonEmptyMap and the passed Every. * * @tparam V1 the value type of the returned NonEmptyMap * @param other the Every to append * @return a new NonEmptyMap that contains all the entries of this NonEmptyMap and all elements of other. */ def ++[V1 >: V](other: Every[(K, V1)]): NonEmptyMap[K, V1] = new NonEmptyMap(toMap ++ other.toVector) // TODO: Have I added these extra ++, etc. methods to Every that take a NonEmptyMap? /** * Returns a new NonEmptyMap containing the entries of this NonEmptyMap and the entries of the passed GenTraversableOnce. * The entry type of the resulting NonEmptyMap is the most specific superclass encompassing the entry types of this NonEmptyMap * and the passed GenTraversableOnce. * * @tparam V1 the value type of the returned NonEmptyMap * @param other the GenTraversableOnce to append * @return a new NonEmptyMap that contains all the elements of this NonEmptyMap followed by all elements of other. */ def ++[V1 >: V](other: org.scalactic.ColCompatHelper.IterableOnce[(K, V1)]): NonEmptyMap[K, V1] = if (other.isEmpty) this else new NonEmptyMap(toMap ++ other.toMap) /** * Returns a new NonEmptyMap with the given entry added. * *

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

* * @param entry the element to add to this NonEmptyMap * @return a new NonEmptyMap consisting of element followed by all elements of this NonEmptyMap. */ final def +:[V1 >: V](entry: (K, V1)): NonEmptyMap[K, V1] = new NonEmptyMap(toMap + entry) /** * As with ++, returns a new NonEmptyMap containing the entries of this NonEmptyMap and the entries of the passed NonEmptyMap. * The entry type of the resulting NonEmptyMap is the most specific superclass encompassing the entry types of this and the passed NonEmptyMap. * * It differs from ++ in that the right operand determines the type of the resulting collection rather than the left one. Mnemonic: the COLon is on the side of the new COLlection type. * * @tparam V1 the value type of the returned NonEmptyMap * @param other the NonEmptyMap to add * @return a new NonEmptyMap that contains all the elements of this NonEmptyMap and all elements of other. */ def ++:[V1 >: V](other: NonEmptyMap[K, V1]): NonEmptyMap[K, V1] = new NonEmptyMap(toMap ++ other.toMap) /** * As with ++, returns a new NonEmptyMap containing the entries of this NonEmptyMap and the entries of the passed Every. * The entry type of the resulting NonEmptyMap is the most specific superclass encompassing the entry types of this NonEmptyMap and the passed Every. * * It differs from ++ in that the right operand determines the type of the resulting collection rather than the left one. Mnemonic: the COLon is on the side of the new COLlection type. * * @tparam V1 the value type of the returned NonEmptyMap * @param other the Every to append * @return a new NonEmptyMap that contains all the entries of this NonEmptyMap and all elements of other. */ def ++:[V1 >: V](other: Every[(K, V1)]): NonEmptyMap[K, V1] = new NonEmptyMap(toMap ++ other.toVector) /** * Returns a new NonEmptyMap containing the entries of this NonEmptyMap and the entries of the passed GenTraversableOnce. * The entry type of the resulting NonEmptyMap is the most specific superclass encompassing the entry types of this NonEmptyMap * and the passed GenTraversableOnce. * * @tparam V1 the value type of the returned NonEmptyMap * @param other the GenTraversableOnce to append * @return a new NonEmptyMap that contains all the elements of this NonEmptyMap followed by all elements of other. */ def ++:[V1 >: V](other: org.scalactic.ColCompatHelper.IterableOnce[(K, V1)]): NonEmptyMap[K, V1] = if (other.isEmpty) this else new NonEmptyMap(toMap ++ other.toMap) /** * Returns a new NonEmptyMap with the given entry added. * * @param entry the entry to add to this NonEmptyMap * @return a new NonEmptyMap consisting of all entries of this NonEmptyMap and entry. */ def +[V1 >: V](entry: (K, V1)): NonEmptyMap[K, V1] = new NonEmptyMap(toMap + entry) /** * Returns a new NonEmptyMap with the given entries added. * * @param entries the entries to add to this NonEmptyMap * @return a new NonEmptyMap consisting of all entries of this NonEmptyMap and entries. */ def +[V1 >: V](entries: (K, V1)*): NonEmptyMap[K, V1] = new NonEmptyMap(toMap ++ entries) /** * Appends all entries of this NonEmptyMap to a string builder. The written text will consist of a concatenation of the result of invoking toString * on of every entry of this NonEmptyMap, without any separator string. * * @param sb the string builder to which entries will be appended * @return the string builder, sb, to which entries were appended. */ final def addString(sb: StringBuilder): StringBuilder = toMap.addString(sb) /** * Appends all entries of this NonEmptyMap 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 NonEmptyMap, separated by the string sep. * * @param sb the string builder to which entries will be appended * @param sep the separator string * @return the string builder, sb, to which elements were appended. */ final def addString(sb: StringBuilder, sep: String): StringBuilder = toMap.addString(sb, sep) /** * Appends all entries of this NonEmptyMap 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 NonEmptyMap, * 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. */ final def addString(sb: StringBuilder, start: String, sep: String, end: String): StringBuilder = toMap.addString(sb, start, sep, end) /** * Selects an value by its key in the NonEmptyMap. * * @return the value of this NonEmptyMap at key k. */ final def apply(k: K): V = toMap(k) /** * Finds the first entry of this NonEmptyMap 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 entry for which it is defined, or None if * the partial function was not defined for any entry. */ final def collectFirst[U](pf: PartialFunction[(K, V), U]): Option[U] = toMap.collectFirst(pf) /** * Indicates whether this NonEmptyMap contains a binding for given key. * * @param key the key to look for * @return true if this NonEmptyMap has a binding that is equal (as determined by ==) to key, false otherwise. */ final def contains(key: K): Boolean = toMap.contains(key) /** * Copies entries of this NonEmptyMap to an array. Fills the given array arr with entries of this NonEmptyMap. Copying * will stop once either the end of the current NonEmptyMap is reached, or the end of the array is reached. * * @param arr the array to fill */ final def copyToArray[V1 >: V](arr: Array[(K, V1)]): Unit = toMap.copyToArray(arr) /** * Copies entries of this NonEmptyMap to an array. Fills the given array arr with entries of this NonEmptyMap, beginning at * index start. Copying will stop once either the end of the current NonEmptyMap is reached, or the end of the array is reached. * * @param arr the array to fill * @param start the starting index */ final def copyToArray[V1 >: V](arr: Array[(K, V1)], start: Int): Unit = toMap.copyToArray(arr, start) /** * Copies entries of this NonEmptyMap to an array. Fills the given array arr with at most len entries of this NonEmptyMap, beginning at * index start. Copying will stop once either the end of the current NonEmptyMap 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 */ final def copyToArray[V1 >: V](arr: Array[(K, V1)], start: Int, len: Int): Unit = toMap.copyToArray(arr, start, len) /** * Copies all elements of this NonEmptyMap to a buffer. * * @param buf the buffer to which elements are copied */ final def copyToBuffer[V1 >: V](buf: Buffer[(K, V1)]): Unit = toMap.copyToBuffer(buf) /** * Counts the number of elements in this NonEmptyMap that satisfy a predicate. * * @param p the predicate used to test elements. * @return the number of elements satisfying the predicate p. */ final def count(p: ((K, V)) => Boolean): Int = toMap.count(p) /* override def equals(o: Any): Boolean = o match { case nonEmptyMap: NonEmptyMap[_] => toMap == nonEmptyMap.toMap case _ => false } */ /** * Indicates whether a predicate holds for at least one of the entries of this NonEmptyMap. * * @param p the predicate used to test entries. * @return true if the given predicate p holds for some of the entries of this NonEmptyMap, otherwise false. */ final def exists(p: ((K, V)) => Boolean): Boolean = toMap.exists(p) /** * Finds the first entry of this NonEmptyMap that satisfies the given predicate, if any. * * @param p the predicate used to test elements * @return an Some containing the first element in this NonEmptyMap that satisfies p, or None if none exists. */ final def find(p: ((K, V)) => Boolean): Option[(K, V)] = toMap.find(p) /** * Builds a new NonEmptyMap by applying a function to all entries of this NonEmptyMap and using the entries of the resulting NonEmptyMaps. * * @tparam K1 the key type of the returned NonEmptyMap * @tparam V1 the value type of the returned NonEmptyMap * @param f the function to apply to each entry. * @return a new NonEmptyMap containing entries obtained by applying the given function f to each entry of this NonEmptyMap and concatenating * the entries of resulting NonEmptyMaps. */ final def flatMap[K1, V1](f: ((K, V)) => NonEmptyMap[K1, V1]): NonEmptyMap[K1, V1] = { val buf = new ArrayBuffer[(K1, V1)] for (ele <- toMap) buf ++= f(ele).toMap new NonEmptyMap(buf.toMap) } /** * Folds the entries of this NonEmptyMap using the specified associative binary operator. * *

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

* * @tparam U a type parameter for the binary operator, a supertype of (K, V). * @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 */ final def fold[U >: (K, V)](z: U)(op: (U, U) => U): U = toMap.fold(z)(op) /** * Applies a binary operator to a start value and all elements of this NonEmptyMap, 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 entries of this NonEmptyMap, 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 NonEmptyMap. *

*/ final def foldLeft[B](z: B)(op: (B, (K, V)) => B): B = toMap.foldLeft(z)(op) /** * Applies a binary operator to all entries of this NonEmptyMap 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 entries of this NonEmptyMap, 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 NonEmptyMap. *

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

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

*/ final def groupBy(f: ((K, V)) => K): Map[K, NonEmptyMap[K, V]] = { val mapKToMap = toMap.groupBy(f) mapKToMap.mapValues { list => new NonEmptyMap(list) }.toMap } /** * Partitions entries into fixed size NonEmptyMaps. * * @param size the number of entries per group * @return An iterator producing NonEmptyMaps of size size, except the last will be truncated if the entries don't divide evenly. */ final def grouped(size: Int): Iterator[NonEmptyMap[K, V]] = { val itOfMap = toMap.grouped(size) itOfMap.map { list => new NonEmptyMap(list) } } /** * Returns true to indicate this NonEmptyMap has a definite size, since all NonEmptyMaps are strict collections. */ final def hasDefiniteSize: Boolean = true // override def hashCode: Int = toMap.hashCode /** * Selects the first element of this NonEmptyMap. * * @return the first element of this NonEmptyMap. */ final def head: (K, V) = toMap.head // Methods like headOption I can't get rid of because of the implicit conversion to GenTraversable. // Users can call any of the methods I've left out on a NonEmptyMap, and get whatever Map would return // for that method call. Eventually I'll probably implement them all to save the implicit conversion. /** * Selects the first element of this NonEmptyMap and returns it wrapped in a Some. * * @return the first element of this NonEmptyMap, wrapped in a Some. */ final def headOption: Option[(K, V)] = toMap.headOption /** * Tests whether this NonEmptyMap contains given key. * * @param key the key to test * @return true if this NonEmptyMap contains a binding for the given key, false otherwise. */ final def isDefinedAt(key: K): Boolean = toMap.isDefinedAt(key) /** * Returns false to indicate this NonEmptyMap, like all NonEmptyMaps, is non-empty. * * @return false */ final def isEmpty: Boolean = false /** * Returns true to indicate this NonEmptyMap, like all NonEmptyMaps, can be traversed repeatedly. * * @return true */ final def isTraversableAgain: Boolean = true /** * Creates and returns a new iterator over all elements contained in this NonEmptyMap. * * @return the new iterator */ final def iterator: Iterator[(K, V)] = toMap.iterator /** * Selects the last entry of this NonEmptyMap. * * @return the last entry of this NonEmptyMap. */ final def last: (K, V) = toMap.last /** * Returns the last element of this NonEmptyMap, wrapped in a Some. * * @return the last element, wrapped in a Some. */ final def lastOption: Option[(K, V)] = toMap.lastOption // Will always return a Some /** * Builds a new NonEmptyMap by applying a function to all entries of this NonEmptyMap. * * @tparam K1 the key type of the returned NonEmptyMap. * @tparam V1 the value type of the returned NonEmptyMap. * @param f the function to apply to each element. * @return a new NonEmptyMap resulting from applying the given function f to each element of this NonEmptyMap and collecting the results. */ final def map[K1, V1](f: ((K, V)) => (K1, V1)): NonEmptyMap[K1, V1] = new NonEmptyMap(toMap.map(f)) /** * Finds the largest entry. * * @return the largest entry of this NonEmptyMap. */ final def max[U >: (K, V)](implicit cmp: Ordering[U]): (K, V) = toMap.max(cmp) /** * Finds the largest result after applying the given function to every entry. * * @return the largest result of applying the given function to every entry of this NonEmptyMap. */ final def maxBy[U](f: ((K, V)) => U)(implicit cmp: Ordering[U]): (K, V) = toMap.maxBy(f)(cmp) /** * Finds the smallest entry. * * @return the smallest entry of this NonEmptyMap. */ final def min[U >: (K, V)](implicit cmp: Ordering[U]): (K, V) = toMap.min(cmp) /** * Finds the smallest result after applying the given function to every entry. * * @return the smallest result of applying the given function to every entry of this NonEmptyMap. */ final def minBy[U](f: ((K, V)) => U)(implicit cmp: Ordering[U]): (K, V) = toMap.minBy(f)(cmp) /** * Displays all entries of this NonEmptyMap in a string. * * @return a string representation of this NonEmptyMap. In the resulting string, the result of invoking toString on all entries of this * NonEmptyMap follow each other without any separator string. */ final def mkString: String = toMap.mkString /** * Displays all entries of this NonEmptyMap in a string using a separator string. * * @param sep the separator string * @return a string representation of this NonEmptyMap. In the resulting string, the result of invoking toString on all entries of this * NonEmptyMap are separated by the string sep. */ final def mkString(sep: String): String = toMap.mkString(sep) /** * Displays all entries of this NonEmptyMap 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 NonEmptyMap. 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 entries of this NonEmptyMap are * separated by the string sep. */ final def mkString(start: String, sep: String, end: String): String = toMap.mkString(start, sep, end) /** * Returns true to indicate this NonEmptyMap, like all NonEmptyMaps, is non-empty. * * @return true */ final def nonEmpty: Boolean = true /** * The result of multiplying all the entries of this NonEmptyMap. * *

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

* * @return the product of all elements */ final def product[U >: (K, V)](implicit num: Numeric[U]): U = toMap.product(num) /** * Reduces the entries of this NonEmptyMap using the specified associative binary operator. * *

* The order in which operations are performed on entries 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 NonEmptyMap. */ final def reduce[U >: (K, V)](op: (U, U) => U): U = toMap.reduce(op) /** * Applies a binary operator to all entries of this NonEmptyMap, 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 entries of this NonEmptyMap, going left to right: * *
    * op(...op(op(x_1, x_2), x_3), ..., x_n)
    * 
* *

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

*/ final def reduceLeft[U >: (K, V)](op: (U, (K, V)) => U): U = toMap.reduceLeft(op) /** * Applies a binary operator to all entries of this NonEmptyMap, 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) *

*/ final def reduceLeftOption[U >: (K, V)](op: (U, (K, V)) => U): Option[U] = toMap.reduceLeftOption(op) final def reduceOption[U >: (K, V)](op: (U, U) => U): Option[U] = toMap.reduceOption(op) /** * Applies a binary operator to all entries of this NonEmptyMap, 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 entries of this NonEmptyMap, going right to left: * *
    * op(x_1, op(x_2, ... op(x_{n-1}, x_n)...))
    * 
* *

* where x1, ..., xn are the entries of this NonEmptyMap. *

*/ final def reduceRight[U >: (K, V)](op: ((K, V), U) => U): U = toMap.reduceRight(op) /** * Applies a binary operator to all entries of this NonEmptyMap, 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) */ final def reduceRightOption[U >: (K, V)](op: ((K, V), U) => U): Option[U] = toMap.reduceRightOption(op) /** * Checks if the given GenIterable contains the same entries in the same order as this NonEmptyMap. * * @param that the GenIterable with which to compare * @return true, if both this NonEmptyMap and the given GenIterable contain the same entries * in the same order, false otherwise. */ final def sameElements[U >: (K, V)](that: GenIterable[U]): Boolean = toMap.sameElements(that) /** * Checks if the given Every contains the same entries in the same order as this NonEmptyMap. * * @param that the Every with which to compare * @return true, if both this and the given Every contain the same entries * in the same order, false otherwise. */ final def sameElements[U >: (K, V)](that: Every[U]): Boolean = toMap.sameElements(that.toVector) /** * Checks if the given NonEmptyMap contains the same entries in the same order as this NonEmptyMap. * * @param that the NonEmptyMap with which to compare * @return true, if both this and the given NonEmptyMap contain the same entries * in the same order, false otherwise. */ final def sameElements[V1 >: V](that: NonEmptyMap[K, V1]): Boolean = toMap.sameElements(that.toMap) /** * Computes a prefix scan of the entries of this NonEmptyMap. * *

* Note: The neutral element z may be applied more than once. *

* * @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 NonEmptyMap containing the prefix scan of the elements in this NonEmptyMap */ final def scan[V1 >: V](z: (K, V1))(op: ((K, V1), (K, V1)) => (K, V1)): NonEmptyMap[K, V1] = new NonEmptyMap(toMap.scan(z)(op).toMap) /** * Groups entries 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 entries per group * @return an iterator producing NonEmptyMaps of size size, except the last and the only element will be truncated * if there are fewer entries than size. */ final def sliding(size: Int): Iterator[NonEmptyMap[K, V]] = toMap.sliding(size).map(new NonEmptyMap(_)) /** * Groups entries 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 entries per group * @param step the distance between the first entries of successive groups * @return an iterator producing NonEmptyMaps of size size, except the last and the only element will be truncated * if there are fewer elements than size. */ final def sliding(size: Int, step: Int): Iterator[NonEmptyMap[K, V]] = toMap.sliding(size, step).map(new NonEmptyMap(_)) /** * The size of this NonEmptyMap. * *

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

* * @return the number of elements in this NonEmptyMap. */ final def size: Int = toMap.size /** * Returns "NonEmptyMap", the prefix of this object's toString representation. * * @return the string "NonEmptyMap" */ def stringPrefix: String = "NonEmptyMap" /** * The result of summing all the elements of this NonEmptyMap. * *

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

* * @return the sum of all elements */ final def sum[U >: (K, V)](implicit num: Numeric[U]): U = toMap.sum(num) import scala.language.higherKinds /** * Converts this NonEmptyMap into a collection of type Col by copying all entries. * * @tparam Col the collection type to build. * @return a new collection containing all entries of this NonEmptyMap. */ //final def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, (K, V), Col[(K, V) @uV]]): Col[(K, V) @uV] = toMap.to[Col](cbf) final def to[Col[_]](factory: org.scalactic.ColCompatHelper.Factory[(K, V), Col[(K, V) @ uV]]): Col[(K, V) @ uV] = toMap.to(factory) /** * Converts this NonEmptyMap to an array. * * @return an array containing all entries of this NonEmptyMap. A ClassTag must be available for the entry type of this NonEmptyMap. */ final def toArray[U >: (K, V)](implicit classTag: ClassTag[U]): Array[U] = toMap.toArray /** * Converts this NonEmptyMap to a Vector. * * @return a Vector containing all entries of this NonEmptyMap. */ final def toVector: Vector[(K, V)] = toMap.toVector /** * Converts this NonEmptyMap to a mutable buffer. * * @return a buffer containing all entries of this NonEmptyMap. */ final def toBuffer[U >: (K, V)]: Buffer[U] = toMap.toBuffer /** * Converts this NonEmptyMap to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all entries of this NonEmptyMap. */ final def toIndexedSeq: collection.immutable.IndexedSeq[(K, V)] = toMap.toVector /** * Converts this NonEmptyMap to an iterable collection. * * @return an Iterable containing all entries of this NonEmptyMap. */ final def toIterable: Iterable[(K, V)] = toMap.toIterable /** * Returns an Iterator over the entries in this NonEmptyMap. * * @return an Iterator containing all entries of this NonEmptyMap. */ final def toIterator: Iterator[(K, V)] = toMap.toIterator /** * Converts this NonEmptyMap to an immutable IndexedSeq. * * @return an immutable IndexedSeq containing all entries of this NonEmptyMap. */ final def toSeq: collection.immutable.Seq[(K, V)] = collection.immutable.Seq.empty[(K, V)] ++ toMap.toSeq /** * Converts this NonEmptyMap to a set. * * @return a set containing all entries of this NonEmptyMap. */ final def toSet[U >: (K, V)]: Set[U] = toMap.toSet /** * Converts this NonEmptyMap to a stream. * * @return a stream containing all entries of this NonEmptyMap. */ final def toStream: Stream[(K, V)] = toMap.toStream /** * Returns a string representation of this NonEmptyMap. * * @return the string "NonEmptyMap" followed by the result of invoking toString on * this NonEmptyMap's elements, surrounded by parentheses. */ override def toString: String = "NonEmptyMap(" + toMap.mkString(", ") + ")" /** * Converts this NonEmptyMap of pairs into two Iterables 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 NonEmptyMap is a pair. * @return a pair of NonEmptyMaps, containing the first and second half, respectively, of each element pair of this NonEmptyMap. */ final def unzip[L, R](implicit asPair: ((K, V)) => (L, R)): (scala.collection.immutable.Iterable[L], scala.collection.immutable.Iterable[R]) = toMap.unzip /** * Converts this NonEmptyMap of triples into three NonEmptyMaps of the first, second, and and third entry of each triple. * * @tparam L the type of the first member of the entry triples * @tparam R the type of the second member of the entry triples * @tparam R the type of the third member of the entry triples * @param asTriple an implicit conversion that asserts that the entry type of this NonEmptyMap is a triple. * @return a triple of NonEmptyMaps, containing the first, second, and third member, respectively, of each entry triple of this NonEmptyMap. */ final def unzip3[L, M, R](implicit asTriple: ((K, V)) => (L, M, R)): (scala.collection.immutable.Iterable[L], scala.collection.immutable.Iterable[M], scala.collection.immutable.Iterable[R]) = toMap.unzip3 /** * A copy of this NonEmptyMap with one single replaced entry. * * @param key the key of the replacement * @param value the replacing value * @return a copy of this NonEmptyMap with the value at key replaced by the given value. */ final def updated[V1 >: V](key: K, value: V1): NonEmptyMap[K, V1] = new NonEmptyMap(toMap.updated(key, value)) /** * Returns a NonEmptyMap formed from this NonEmptyMap and an iterable collection by combining corresponding * entries in pairs. If one of the two collections is shorter than the other, placeholder entries will be used to extend the * shorter collection to the length of the longer. * * @tparam O the type of the second half of the returned pairs * @tparam V1 the subtype of the value type of this NonEmptyMap * @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 NonEmptyMap is shorter than that Iterable. * @param otherElem the element to be used to fill up the result if that Iterable is shorter than this NonEmptyMap. * @return a new NonEmptyMap containing pairs consisting of corresponding entries of this NonEmptyMap and that. The * length of the returned collection is the maximum of the lengths of this NonEmptyMap and that. If this NonEmptyMap * is shorter than that, thisElem values are used to pad the result. If that is shorter than this * NonEmptyMap, thatElem values are used to pad the result. */ final def zipAll[O, V1 >: V](other: collection.Iterable[O], thisElem: (K, V1), otherElem: O): NonEmptyMap[(K, V1), O] = new NonEmptyMap(toMap.zipAll(other, thisElem, otherElem).toMap) /** * Zips this NonEmptyMap with its indices. * * @return A new NonEmptyMap containing pairs consisting of all elements of this NonEmptyMap paired with their index. Indices start at 0. */ final def zipWithIndex[V1 >: V]: NonEmptyMap[(K, V1), Int] = new NonEmptyMap(toMap.zipWithIndex.toMap) } /** * Companion object for class NonEmptyMap. */ object NonEmptyMap { /** * Constructs a new NonEmptyMap given at least one element. * * @tparam K the type of the key contained in the new NonEmptyMap * @tparam V the type of the value contained in the new NonEmptyMap * @param firstElement the first element (with index 0) contained in this NonEmptyMap * @param otherElements a varargs of zero or more other elements (with index 1, 2, 3, ...) contained in this NonEmptyMap */ def apply[K, V](firstElement: (K, V), otherElements: (K, V)*): NonEmptyMap[K, V] = new NonEmptyMap(otherElements.toMap + firstElement) /** * Variable argument extractor for NonEmptyMaps. * * @tparam K the type of the key contained in the NonEmptyMap * @tparam V the type of the value contained in the NonEmptyMap * @param nonEmptyMap: the NonEmptyMap containing the elements to extract * @return an Seq containing this NonEmptyMaps elements, wrapped in a Some */ def unapplySeq[K, V](nonEmptyMap: NonEmptyMap[K, V]): Option[Seq[(K, V)]] = Some(nonEmptyMap.toSeq) /** * Optionally construct a NonEmptyMap containing the elements, if any, of a given GenSeq. * * @tparam K the type of the key contained in the new NonEmptyMap * @tparam V the type of the value contained in the new NonEmptyMap * @param seq the GenSeq with which to construct a NonEmptyMap * @return a NonEmptyMap containing the elements of the given GenSeq, if non-empty, wrapped in * a Some; else None if the GenSeq is empty */ def from[K, V](seq: GenSeq[(K, V)]): Option[NonEmptyMap[K, V]] = seq.headOption match { case None => None case Some(first) => Some(new NonEmptyMap(scala.collection.immutable.Map.empty[K, V] ++ seq.tail.toMap + first)) } def from[K, V](map: scala.collection.GenMap[K, V]): Option[NonEmptyMap[K, V]] = map.headOption match { case None => None case Some(first) => Some(new NonEmptyMap(scala.collection.immutable.Map.empty[K, V] ++ map)) } import scala.language.implicitConversions /** * Implicit conversion from NonEmptyMap to Map. * *

* One use case for this implicit conversion is to enable GenSeq[NonEmptyMap]s to be flattened. * Here's an example: *

* *
    * scala> Vector(NonEmptyMap(1, 2, 3), NonEmptyMap(3, 4), NonEmptyMap(5, 6, 7, 8)).flatten
    * res0: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 3, 4, 5, 6, 7, 8)
    * 
* * @tparam K the type of the key contained in the NonEmptyMap * @tparam V the type of the value contained in the NonEmptyMap * @param nonEmptyMap the NonEmptyMap to convert to a Map * @return a Map containing the elements, in order, of this NonEmptyMap */ implicit def nonEmptyMapToMap[K, V](nonEmptyMap: NonEmptyMap[K, V]): scala.collection.immutable.Map[K, V] = nonEmptyMap.toMap }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy