Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Add Map operations. #137

Merged
merged 8 commits into from
Aug 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ For more information, see the [CONTRIBUTING](CONTRIBUTING.md) file.
- [x] `diff`
- [x] `drop` / `dropRight` / `dropWhile`
- [x] `empty`
- [x] `filter` / `filterNot`
- [x] `filter` / `filterNot` / `filterKeys`
- [x] `groupBy`
- [x] `init`
- [x] `intersect`
Expand All @@ -161,13 +161,15 @@ For more information, see the [CONTRIBUTING](CONTRIBUTING.md) file.
- [x] `++:` / `prependAll`
- [x] `flatMap`
- [x] `grouped`
- [x] `map`
- [x] `keys` / `keySet` / `keysIterator`
- [x] `map` / `mapValues`
- [x] `merged`
- [x] `padTo`
- [x] `permutations`
- [x] `scan` / `scanLeft` / `scanRight`
- [x] `sliding`
- [x] `unzip`
- [x] `values` / `valuesIterator`
- [x] `zip` / `zipWithIndex`

### In-place mutating operations
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Convenient setting that allows writing `set scalaVersion := dotty.value` in sbt shell to switch from Scala to Dotty
val dotty = settingKey[String]("dotty version")
dotty in ThisBuild := "0.2.0-RC1"
dotty in ThisBuild := "0.3.0-bin-20170808-a662424-NIGHTLY"

val commonSettings = Seq(
organization := "ch.epfl.scala",
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/strawman/collection/Iterable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -866,3 +866,5 @@ trait IterableOps[+A, +CC[X], +C] extends Any {
}

}

object Iterable extends IterableFactory.Delegate[Iterable](immutable.Iterable)
69 changes: 68 additions & 1 deletion src/main/scala/strawman/collection/Map.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package collection

import collection.mutable.Builder

import scala.{Any, Boolean, ClassCastException, Equals, Int, NoSuchElementException, None, Nothing, Option, Ordering, PartialFunction, Some, `inline`, throws}
import scala.{Any, Boolean, ClassCastException, Equals, Int, NoSuchElementException, None, Nothing, Option, Ordering, PartialFunction, Serializable, Some, `inline`, throws}
import scala.annotation.unchecked.uncheckedVariance
import scala.util.hashing.MurmurHash3

Expand Down Expand Up @@ -62,6 +62,73 @@ trait MapOps[K, +V, +CC[X, Y] <: Map[X, Y], +C <: Map[K, V]]
case Some(value) => value
}

override /*PartialFunction*/ def applyOrElse[K1 <: K, V1 >: V](x: K1, default: K1 => V1): V1 = getOrElse(x, default(x))

/** Collects all keys of this map in a set.
* @return a set containing all keys of this map.
*/
def keySet: Set[K] = new DefaultKeySet

/** The implementation class of the set returned by `keySet`.
*/
protected class DefaultKeySet extends Set[K] with Serializable {
def contains(key: K) = MapOps.this.coll.contains(key)
def iterator() = keysIterator()
override def size = coll.size
override def foreach[U](f: K => U) = keysIterator() foreach f
def iterableFactory: IterableFactory[Set] = Set
def empty: Set[K] = iterableFactory.empty
def diff(that: Set[K]): Set[K] = fromSpecificIterable(iterableFactory.fromIterable(coll).diff(that))
protected[this] def fromSpecificIterable(coll: Iterable[K]): Set[K] = iterableFactory.fromIterable(coll)
protected[this] def newSpecificBuilder(): Builder[K, Set[K]] = iterableFactory.newBuilder()
}

/** Collects all keys of this map in an iterable collection.
*
* @return the keys of this map as an iterable.
*/
def keys: Iterable[K] = keySet

/** Collects all values of this map in an iterable collection.
*
* @return the values of this map as an iterable.
*/
def values: Iterable[V] = View.fromIterator(valuesIterator())

/** Creates an iterator for all keys.
*
* @return an iterator over all keys.
*/
def keysIterator(): Iterator[K] = new Iterator[K] {
val iter = coll.iterator()
def hasNext = iter.hasNext
def next() = iter.next()._1
}

/** Creates an iterator for all values in this map.
*
* @return an iterator over all values that are associated with some key in this map.
*/
def valuesIterator(): Iterator[V] = new Iterator[V] {
val iter = coll.iterator()
def hasNext = iter.hasNext
def next() = iter.next()._2
}

/** Filters this map by retaining only keys satisfying a predicate.
* @param p the predicate used to test keys
* @return an immutable map consisting only of those key value pairs of this map where the key satisfies
* the predicate `p`. The resulting map wraps the original map without copying any elements.
*/
def filterKeys(p: K => Boolean): View[(K, V)] = View.FilterKeys(coll, p)

/** Transforms this map by applying a function to every retrieved value.
* @param f the function used to transform values of this map.
* @return a map view which maps every key of this map
* to `f(this(key))`. The resulting map wraps the original map without copying any elements.
*/
def mapValues[W](f: V => W): View[(K, W)] = View.MapValues(coll, f)

/** Defines the default value computation for the map,
* returned when a key is not found
* The method implemented here throws an exception,
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/strawman/collection/Set.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ trait SetOps[A, +CC[X], +C <: Set[A]]
* @param elem the element to test for membership.
* @return `true` if `elem` is contained in this set, `false` otherwise.
*/
/*@`inline`*/ final def apply(elem: A): Boolean = this.contains(elem)
@`inline` final def apply(elem: A): Boolean = this.contains(elem)

/** Tests whether this set is a subset of another set.
*
Expand Down
9 changes: 9 additions & 0 deletions src/main/scala/strawman/collection/View.scala
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ object View extends IterableFactory[View] {
}
}

case class FilterKeys[K, V](underlying: Iterable[(K, V)], p: K => Boolean) extends View[(K, V)] {
def iterator(): Iterator[(K, V)] = underlying.iterator().filter(kv => p(kv._1))
}

/** A view that partitions an underlying collection into two views */
case class Partition[A](underlying: Iterable[A], p: A => Boolean) {

Expand Down Expand Up @@ -149,6 +153,11 @@ object View extends IterableFactory[View] {
override def knownSize = underlying.knownSize
}

case class MapValues[K, V, W](underlying: Iterable[(K, V)], f: V => W) extends View[(K, W)] {
def iterator(): Iterator[(K, W)] = underlying.iterator().map(kv => (kv._1, f(kv._2)))
override def knownSize: Int = underlying.knownSize
}

/** A view that flatmaps elements of the underlying collection. */
case class FlatMap[A, B](underlying: Iterable[A], f: A => IterableOnce[B]) extends View[B] {
def iterator() = underlying.iterator().flatMap(f)
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/strawman/collection/immutable/Iterable.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package strawman.collection.immutable

import strawman.collection
import strawman.collection.IterableFactory

trait Iterable[+A] extends collection.Iterable[A]
with collection.IterableOps[A, Iterable, Iterable[A]]

object Iterable extends IterableFactory.Delegate[Iterable](List)
16 changes: 14 additions & 2 deletions src/main/scala/strawman/collection/immutable/Map.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ trait Map[K, +V]
with MapOps[K, V, Map, Map[K, V]]

/** Base trait of immutable Maps implementations */
trait MapOps[K, +V, +CC[X, +Y] <: Map[X, Y] with MapOps[X, Y, CC, _], +C <: Map[K, V]]
trait MapOps[K, +V, +CC[X, +Y] <: Map[X, Y] with MapOps[X, Y, CC, CC[X, Y]], +C <: CC[K, V]]
extends IterableOps[(K, V), Iterable, C]
with collection.MapOps[K, V, CC, C] {

protected[this] def coll: CC[K, V]
protected[this] def coll: C

/** Removes a key from this map, returning a new map.
*
Expand All @@ -27,6 +27,18 @@ trait MapOps[K, +V, +CC[X, +Y] <: Map[X, Y] with MapOps[X, Y, CC, _], +C <: Map[
/** Alias for `remove` */
@`inline` final def - (key: K): C = remove(key)

/** Creates a new $coll from this $coll by removing all elements of another
* collection.
*
* @param keys the collection containing the removed elements.
* @return a new $coll that contains all elements of the current $coll
* except one less occurrence of each of the elements of `elems`.
*/
def removeAll(keys: IterableOnce[K]): C = fromSpecificIterable(keys.iterator().foldLeft[CC[K, V]](coll)(_ - _))

/** Alias for `removeAll` */
@`inline` final def -- (keys: IterableOnce[K]): C = removeAll(keys)

/** Creates a new map obtained by updating this map with a given key/value pair.
* @param key the key
* @param value the value
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/strawman/collection/immutable/Set.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ trait SetOps[A, +CC[X], +C <: Set[A] with SetOps[A, Set, C]]
def incl(elem: A): C

/** Alias for `incl` */
/*@`inline`*/ final def + (elem: A): C = incl(elem)
@`inline` final def + (elem: A): C = incl(elem)

/** Creates a new set with a given element removed from this set.
*
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/strawman/collection/immutable/SortedMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ trait SortedMap[K, +V]
with collection.SortedMap[K, V]
with SortedMapOps[K, V, SortedMap, SortedMap[K, V]]

trait SortedMapOps[K, +V, +CC[X, +Y] <: SortedMap[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMap[K, V]]
trait SortedMapOps[K, +V, +CC[X, +Y] <: SortedMap[X, Y] with SortedMapOps[X, Y, CC, _], +C <: CC[K, V]]
extends MapOps[K, V, Map, C]
with collection.SortedMapOps[K, V, CC, C] {

protected[this] def coll: CC[K, V]
protected[this] def coll: C

protected def mapFromIterable[K2, V2](it: collection.Iterable[(K2, V2)]): Map[K2, V2] =
Map.fromIterable(it)
Expand Down