diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 20753409a315..0fcdfcec669c 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -1,7 +1,9 @@ package scala import reflect.ClassTag -import scala.collection.immutable +import scala.collection.{LazyZip2, SeqView, Searching, Stepper, StepperShape} +import scala.collection.immutable.ArraySeq +import scala.collection.mutable.{ArrayBuilder, Builder} opaque type IArray[+T] = Array[_ <: T] @@ -39,15 +41,10 @@ object IArray: extension (arr: IArray[Object]) def length: Int = arr.asInstanceOf[Array[Object]].length extension [T](arr: IArray[T]) def length: Int = arr.asInstanceOf[Array[T]].length - /** Returns this array concatenated with the given array. */ - extension [T](arr: IArray[T]) def ++ [U >: T: ClassTag](that: IArray[U]): IArray[U] = - genericArrayOps(arr) ++ that /** Tests whether this array contains a given value as an element. */ extension [T](arr: IArray[T]) def contains(elem: T): Boolean = - // `genericArrayOps(arr).contains(elem)` does not work because `elem` does not have type `arr.T` - // but we can use `exists` instead, which is how `ArrayOps#contains` itself is implemented: - genericArrayOps(arr).exists(_ == elem) + genericArrayOps(arr).contains(elem.asInstanceOf) /** Copy elements of this array to another array. */ extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U]): Int = @@ -100,7 +97,7 @@ object IArray: /** Flattens a two-dimensional array by concatenating all its rows * into a single array. */ - extension [T](arr: IArray[T]) def flatten[U: ClassTag](using T => Iterable[U]): IArray[U] = + extension [T](arr: IArray[T]) def flatten[U](using asIterable: T => Iterable[U], ct: ClassTag[U]): IArray[U] = genericArrayOps(arr).flatten /** Folds the elements of this array using the specified associative binary operator. */ @@ -236,10 +233,6 @@ object IArray: extension [T](arr: IArray[T]) def splitAt(n: Int): (IArray[T], IArray[T]) = genericArrayOps(arr).splitAt(n) - /** Tests whether this array starts with the given array. */ - extension [T](arr: IArray[T]) def startsWith[U >: T](that: IArray[U], offset: Int = 0): Boolean = - genericArrayOps(arr).startsWith(that) - /** The rest of the array without its first element. */ extension [T](arr: IArray[T]) def tail: IArray[T] = genericArrayOps(arr).tail @@ -260,59 +253,127 @@ object IArray: extension [T](arr: IArray[T]) def toArray: Array[T] = arr.clone.asInstanceOf[Array[T]] - /** Converts an array of pairs into an array of first elements and an array of second elements. */ - extension [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) def unzip: (IArray[U], IArray[V]) = - genericArrayOps(arr).unzip - - /** Returns an array formed from this array and another iterable collection - * by combining corresponding elements in pairs. - * If one of the two collections is longer than the other, its remaining elements are ignored. */ - extension [T](arr: IArray[T]) def zip[U](that: IArray[U]): IArray[(T, U)] = - genericArrayOps(arr).zip(that) + extension [T](arr: IArray[T]) + def ++[U >: T: ClassTag](suffix: IArray[U]): IArray[U] = genericArrayOps(arr) ++ suffix.toSeq + def ++[U >: T: ClassTag](suffix: IterableOnce[U]): IArray[U] = genericArrayOps(arr) ++ suffix + def :+ [U >: T: ClassTag](x: U): IArray[U] = genericArrayOps(arr) :+ x + def :++ [U >: T: ClassTag](suffix: IArray[U]): IArray[U] = genericArrayOps(arr) :++ suffix + def :++ [U >: T: ClassTag](suffix: IterableOnce[U]): IArray[U] = genericArrayOps(arr) :++ suffix + def appended[U >: T: ClassTag](x: U): IArray[U] = genericArrayOps(arr).appended(x) + def appendedAll[U >: T: ClassTag](suffix: IArray[U]): IArray[U] = genericArrayOps(arr).appendedAll(suffix) + def appendedAll[U >: T: ClassTag](suffix: IterableOnce[U]): IArray[U] = genericArrayOps(arr).appendedAll(suffix) + def collect[U: ClassTag](pf: PartialFunction[T, U]): IArray[U] = genericArrayOps(arr).collect(pf) + def collectFirst[U](f: PartialFunction[T, U]): Option[U] = genericArrayOps(arr).collectFirst(f) + def combinations(n: Int): Iterator[IArray[T]] = genericArrayOps(arr).combinations(n) + def concat[U >: T: ClassTag](suffix: IArray[U]): IArray[U] = genericArrayOps(arr).concat(suffix) + def concat[U >: T: ClassTag](suffix: IterableOnce[U]): IArray[U] = genericArrayOps(arr).concat(suffix) + def diff[U >: T](that: IArray[U]): IArray[T] = genericArrayOps(arr).diff(that.toSeq) + def diff[U >: T](that: Seq[U]): IArray[T] = genericArrayOps(arr).diff(that) + def distinct: IArray[T] = genericArrayOps(arr).distinct + def distinctBy[U](f: T => U): IArray[T] = genericArrayOps(arr).distinctBy(f) + def startsWith[U >: T](that: IArray[U]): Boolean = genericArrayOps(arr).startsWith(that, 0) + def startsWith[U >: T](that: IArray[U], offset: Int): Boolean = genericArrayOps(arr).startsWith(that, offset) + def startsWith[U >: T](that: IterableOnce[U]): Boolean = genericArrayOps(arr).startsWith(that, 0) + def startsWith[U >: T](that: IterableOnce[U], offset: Int): Boolean = genericArrayOps(arr).startsWith(that, offset) + def endsWith[U >: T](that: IArray[U]): Boolean = genericArrayOps(arr).endsWith(that) + def endsWith[U >: T](that: Iterable[U]): Boolean = genericArrayOps(arr).endsWith(that) + def groupBy[K](f: T => K): Map[K, IArray[T]] = genericArrayOps(arr).groupBy(f) + def groupMap[K, U: ClassTag](key: T => K)(f: T => U): Map[K, IArray[U]] = genericArrayOps(arr).groupMap(key)(f) + def grouped(size: Int): Iterator[IArray[T]] = genericArrayOps(arr).grouped(size) + def inits: Iterator[IArray[T]] = genericArrayOps(arr).inits + def intersect[U >: T](that: IArray[U]): IArray[T] = genericArrayOps(arr).intersect(that) + def intersect[U >: T](that: Seq[U]): IArray[T] = genericArrayOps(arr).intersect(that) + def lazyZip[U](that: IArray[U]): LazyZip2[T, U, IArray[T]] = genericArrayOps(arr).lazyZip[U](that).asInstanceOf[LazyZip2[T, U, IArray[T]]] + def lazyZip[U](that: Iterable[U]): LazyZip2[T, U, IArray[T]] = genericArrayOps(arr).lazyZip[U](that).asInstanceOf[LazyZip2[T, U, IArray[T]]] + def lengthCompare(len: Int): Int = genericArrayOps(arr).lengthCompare(len) + def padTo[U >: T: ClassTag](len: Int, elem: U): IArray[U] = genericArrayOps(arr).padTo(len, elem) + def partitionMap[T1: ClassTag, T2: ClassTag](f: T => Either[T1, T2]): (IArray[T1], IArray[T2]) = genericArrayOps(arr).partitionMap(f) + def patch[U >: T: ClassTag](from: Int, other: IterableOnce[U], replaced: Int): IArray[U] = genericArrayOps(arr).patch(from, other, replaced) + def permutations: Iterator[IArray[T]] = genericArrayOps(arr).permutations + def prepended[U >: T: ClassTag](x: U): IArray[U] = genericArrayOps(arr).prepended(x) + def prependedAll[U >: T: ClassTag](prefix: IterableOnce[U]): IArray[U] = genericArrayOps(arr).prependedAll(prefix) + def reverseIterator: Iterator[T] = genericArrayOps(arr).reverseIterator + def search[U >: T](elem: U)(using Ordering[U]): Searching.SearchResult = arr.toSeq.search(elem) + def search[U >: T](elem: U, from: Int, to: Int)(using Ordering[U]): Searching.SearchResult = arr.toSeq.search(elem, from, to) + def sizeCompare(that: IArray[Any]): Int = arr.toSeq.sizeCompare(that) + def sizeCompare(that: Iterable[_]): Int = arr.toSeq.sizeCompare(that) + def sizeCompare(otherSize: Int): Int = genericArrayOps(arr).sizeCompare(otherSize) + def sliding(size: Int, step: Int = 1): Iterator[IArray[T]] = genericArrayOps(arr).sliding(size, step) + def stepper[S <: Stepper[_]](using StepperShape[T, S]): S = genericArrayOps(arr).stepper[S] + def tails: Iterator[IArray[T]] = genericArrayOps(arr).tails + def tapEach[U](f: (T) => U): IArray[T] = + arr.toSeq.foreach(f) + arr + def transpose[U](implicit asArray: T => IArray[U]): IArray[IArray[U]] = + genericArrayOps(arr).transpose(using asArray.asInstanceOf[T => Array[U]]) + def unzip[T1, T2](using asPair: T => (T1, T2), ct1: ClassTag[T1], ct2: ClassTag[T2]): (IArray[T1], IArray[T2]) = genericArrayOps(arr).unzip + def unzip3[T1, T2, T3](using asTriple: T => (T1, T2, T3), ct1: ClassTag[T1], ct2: ClassTag[T2], ct3: ClassTag[T3]): (IArray[T1], IArray[T2], IArray[T3]) = genericArrayOps(arr).unzip3 + def updated[U >: T: ClassTag](index: Int, elem: U): IArray[U] = genericArrayOps(arr).updated(index, elem) + def view: SeqView[T] = genericArrayOps(arr).view + def withFilter(p: T => Boolean): WithFilter[T] = new WithFilter(p, arr) + def zip[U](that: IArray[U]): IArray[(T, U)] = genericArrayOps(arr).zip(that) + def zip[U](that: IterableOnce[U]): IArray[(T, U)] = genericArrayOps(arr).zip(that) + def zipAll[T1 >: T, U](that: IArray[U], thisElem: T1, thatElem: U): IArray[(T1, U)] = genericArrayOps(arr).zipAll(that, thisElem, thatElem) + def zipAll[T1 >: T, U](that: Iterable[U], thisElem: T1, thatElem: U): IArray[(T1, U)] = genericArrayOps(arr).zipAll(that, thisElem, thatElem) + def zipWithIndex: IArray[(T, Int)] = genericArrayOps(arr).zipWithIndex + + extension [T, U >: T: ClassTag](prefix: IterableOnce[T]) + def ++:(arr: IArray[U]): IArray[U] = genericArrayOps(arr).prependedAll(prefix) + + extension [T, U >: T: ClassTag](prefix: IArray[T]) + def ++:(arr: IArray[U]): IArray[U] = genericArrayOps(arr).prependedAll(prefix) + + extension [T, U >: T: ClassTag](x: T) + def +:(arr: IArray[U]): IArray[U] = genericArrayOps(arr).prepended(x) /** Conversion from IArray to immutable.ArraySeq */ - extension [T](arr: IArray[T]) def toSeq: immutable.ArraySeq[T] = - immutable.ArraySeq.unsafeWrapArray(arr.asInstanceOf[Array[T]]) + implicit def genericWrapArray[T](arr: IArray[T]): ArraySeq[T] = + if arr eq null then null else ArraySeq.unsafeWrapArray(arr) /** Conversion from IArray to immutable.ArraySeq */ - extension [T <: AnyRef](arr: IArray[T]) def toSeq: immutable.ArraySeq[T] = - immutable.ArraySeq.ofRef(arr.asInstanceOf[Array[T]]) + implicit def wrapRefArray[T <: AnyRef](arr: IArray[T]): ArraySeq.ofRef[T] = + // Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef] + // is as good as another for all T <: AnyRef. Instead of creating 100,000,000 + // unique ones by way of this implicit, let's share one. + if (arr eq null) null + else if (arr.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]] + else ArraySeq.ofRef(arr.asInstanceOf[Array[T]]) /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Int]) def toSeq: immutable.ArraySeq[Int] = - immutable.ArraySeq.ofInt(arr.asInstanceOf[Array[Int]]) + implicit def wrapIntArray(arr: IArray[Int]): ArraySeq.ofInt = + if (arr ne null) new ArraySeq.ofInt(arr.asInstanceOf[Array[Int]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Double]) def toSeq: immutable.ArraySeq[Double] = - immutable.ArraySeq.ofDouble(arr.asInstanceOf[Array[Double]]) + implicit def wrapDoubleIArray(arr: IArray[Double]): ArraySeq.ofDouble = + if (arr ne null) new ArraySeq.ofDouble(arr.asInstanceOf[Array[Double]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Long]) def toSeq: immutable.ArraySeq[Long] = - immutable.ArraySeq.ofLong(arr.asInstanceOf[Array[Long]]) + implicit def wrapLongIArray(arr: IArray[Long]): ArraySeq.ofLong = + if (arr ne null) new ArraySeq.ofLong(arr.asInstanceOf[Array[Long]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Float]) def toSeq: immutable.ArraySeq[Float] = - immutable.ArraySeq.ofFloat(arr.asInstanceOf[Array[Float]]) + implicit def wrapFloatIArray(arr: IArray[Float]): ArraySeq.ofFloat = + if (arr ne null) new ArraySeq.ofFloat(arr.asInstanceOf[Array[Float]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Char]) def toSeq: immutable.ArraySeq[Char] = - immutable.ArraySeq.ofChar(arr.asInstanceOf[Array[Char]]) + implicit def wrapCharIArray(arr: IArray[Char]): ArraySeq.ofChar = + if (arr ne null) new ArraySeq.ofChar(arr.asInstanceOf[Array[Char]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Byte]) def toSeq: immutable.ArraySeq[Byte] = - immutable.ArraySeq.ofByte(arr.asInstanceOf[Array[Byte]]) + implicit def wrapByteIArray(arr: IArray[Byte]): ArraySeq.ofByte = + if (arr ne null) new ArraySeq.ofByte(arr.asInstanceOf[Array[Byte]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Short]) def toSeq: immutable.ArraySeq[Short] = - immutable.ArraySeq.ofShort(arr.asInstanceOf[Array[Short]]) + implicit def wrapShortIArray(arr: IArray[Short]): ArraySeq.ofShort = + if (arr ne null) new ArraySeq.ofShort(arr.asInstanceOf[Array[Short]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Boolean]) def toSeq: immutable.ArraySeq[Boolean] = - immutable.ArraySeq.ofBoolean(arr.asInstanceOf[Array[Boolean]]) + implicit def wrapBooleanIArray(arr: IArray[Boolean]): ArraySeq.ofBoolean = + if (arr ne null) new ArraySeq.ofBoolean(arr.asInstanceOf[Array[Boolean]]) else null /** Conversion from IArray to immutable.ArraySeq */ - extension (arr: IArray[Unit]) def toSeq: immutable.ArraySeq[Unit] = - immutable.ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]]) + implicit def wrapUnitIArray(arr: IArray[Unit]): ArraySeq.ofUnit = + if (arr ne null) new ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]]) else null /** Convert an array into an immutable array without copying, the original array * must _not_ be mutated after this or the guaranteed immutablity of IArray will @@ -363,6 +424,25 @@ object IArray: /** An immutable array with given elements. */ def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*) + /** Build an array from the iterable collection. + * + * {{{ + * scala> val a = Array.from(Seq(1, 5)) + * val a: Array[Int] = Array(1, 5) + * + * scala> val b = Array.from(Range(1, 5)) + * val b: Array[Int] = Array(1, 2, 3, 4) + * }}} + * + * @param it the iterable collection + * @return an array consisting of elements of the iterable collection + */ + def from[A : ClassTag](it: IterableOnce[A]): Array[A] = + Array.from(it) + + def newBuilder[T](using t: ClassTag[T]): Builder[T, IArray[T]] = + ArrayBuilder.make[T].mapResult(IArray.unsafeFromArray) + /** Concatenates all arrays into a single immutable array. * * @param xss the given immutable arrays @@ -391,7 +471,6 @@ object IArray: * @param elem the element computation */ def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): IArray[IArray[T]] = - // We cannot avoid a cast here as Array.fill creates inner arrays out of our control: Array.fill(n1, n2)(elem) /** Returns a three-dimensional immutable array that contains the results of some element computation a number @@ -512,6 +591,17 @@ object IArray: */ def iterate[T: ClassTag](start: T, len: Int)(f: T => T): IArray[T] = Array.iterate(start, len)(f) + /** Compare two arrays per element. + * + * A more efficient version of `xs.sameElements(ys)`. + * + * @param xs an array of AnyRef + * @param ys an array of AnyRef + * @return true if corresponding elements are equal + */ + def equals(xs: IArray[AnyRef], ys: IArray[AnyRef]): Boolean = + Array.equals(xs.asInstanceOf[Array[AnyRef]], ys.asInstanceOf[Array[AnyRef]]) + /** Returns a decomposition of the array into a sequence. This supports * a pattern match like `{ case IArray(x,y,z) => println('3 elements')}`. * @@ -521,4 +611,65 @@ object IArray: def unapplySeq[T](x: IArray[T]): Array.UnapplySeqWrapper[_ <: T] = Array.unapplySeq(x) -end IArray \ No newline at end of file + /** A lazy filtered array. No filtering is applied until one of `foreach`, `map` or `flatMap` is called. */ + class WithFilter[T](p: T => Boolean, xs: IArray[T]): + + /** Apply `f` to each element for its side effects. + * Note: [U] parameter needed to help scalac's type inference. + */ + def foreach[U](f: T => U): Unit = { + val len = xs.length + var i = 0 + while(i < len) { + val x = xs(i) + if(p(x)) f(x) + i += 1 + } + } + + /** Builds a new array by applying a function to all elements of this array. + * + * @param f the function to apply to each element. + * @tparam U the element type of the returned array. + * @return a new array resulting from applying the given function + * `f` to each element of this array and collecting the results. + */ + def map[U: ClassTag](f: T => U): IArray[U] = { + val b = IArray.newBuilder[U] + var i = 0 + while (i < xs.length) { + val x = xs(i) + if(p(x)) b += f(x) + i = i + 1 + } + b.result() + } + + /** Builds a new array by applying a function to all elements of this array + * and using the elements of the resulting collections. + * + * @param f the function to apply to each element. + * @tparam U the element type of the returned array. + * @return a new array resulting from applying the given collection-valued function + * `f` to each element of this array and concatenating the results. + */ + def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = { + val b = IArray.newBuilder[U] + var i = 0 + while(i < xs.length) { + val x = xs(i) + if(p(x)) b ++= f(xs(i)) + i += 1 + } + b.result() + } + + def flatMap[BS, U](f: T => BS)(using asIterable: BS => Iterable[U], m: ClassTag[U]): IArray[U] = + flatMap[U](x => asIterable(f(x))) + + /** Creates a new non-strict filter which combines this filter with the given predicate. */ + def withFilter(q: T => Boolean): WithFilter[T] = new WithFilter[T](a => p(a) && q(a), xs) + + end WithFilter + +end IArray diff --git a/tests/run/IArrayOps.check b/tests/run/IArrayOps.check new file mode 100644 index 000000000000..847906991768 --- /dev/null +++ b/tests/run/IArrayOps.check @@ -0,0 +1,162 @@ +ArraySeq(1, 2, 3) +true +false +ArraySeq(1, 9, 3) +ArraySeq(1, a, 3) +ArraySeq(1, 2, 3, 0) +ArraySeq(1, 1, 2, 3) +ArraySeq(1, 5, 4, 3) +1 +1 +ArraySeq(1, 5, 4, 3) +ArraySeq(5, 4, 3) +ArraySeq() +ArraySeq(1, 2, 3, 5, 4, 5, 6) +ArraySeq(1, 2, 3, 5, 4, 5, 6) +ArraySeq(1, 2, 3, 7) +ArraySeq(8, 1, 2, 3) +ArraySeq(1, 2, 3, 5, 4, 5, 6) +ArraySeq(5, 4, 5, 6, 12, 13, 14) +ArraySeq(12, 13, 14, 5, 4, 5, 6) +123 +1-2-3 +(1,2,3) +ArraySeq(1, 2, 3, 5) +ArraySeq(1, 2, 3, 5, 4, 5, 6) +ArraySeq(1, 2, 3, 1, 4) +ArraySeq(5, 1, 2, 3) +ArraySeq(5, 6, 1, 2, 3) +ArraySeq(2, 6) +Some(2) +List(ArraySeq(1), ArraySeq(2), ArraySeq(3)) +List(ArraySeq(1, 2), ArraySeq(1, 3), ArraySeq(2, 3)) +List(ArraySeq(1, 2, 3)) +ArraySeq(1, 2, 3, 5, 4, 5, 6) +ArraySeq(1, 2, 3, 8, 9) +false +true +false +true +false +ArraySeq(3) +ArraySeq(3) +ArraySeq(1, 2, 3) +ArraySeq(5, 4, 6) +ArraySeq(5, 4) +false +false +true +true +Some(1) +Some(2) +6 +6 +6 +6 +6 +6 +Map(1 -> ArraySeq(1), 2 -> ArraySeq(2), 3 -> ArraySeq(3)) +Map(0 -> ArraySeq(2), 1 -> ArraySeq(1, 3)) +Map(1 -> ArraySeq(1), 2 -> ArraySeq(2), 3 -> ArraySeq(3)) +Map(0 -> ArraySeq(2), 1 -> ArraySeq(1, 3)) +Map(1 -> 1, 2 -> 2, 3 -> 3) +Map(0 -> 2, 1 -> 13) +List(ArraySeq(1, 2), ArraySeq(3)) +0 +1 +-1 +1 +0 +1 +0 +1 +List(ArraySeq(1, 2, 3), ArraySeq(1, 2), ArraySeq(1), ArraySeq()) +List(ArraySeq(1, 2, 3), ArraySeq(2, 3), ArraySeq(3), ArraySeq()) +ArraySeq(1, 2) +ArraySeq(2, 3) +true +3 +ArraySeq(1, 2, 3).lazyZip(ArraySeq(5, 4, 5, 6)) +List((1,5), (2,4), (3,5)) +0 +1 +-1 +3 +Some(3) +3 +Some(3) +1 +Some(1) +1 +Some(1) +123 +1-2-3 +(1,2,3) +ArraySeq((1,5), (2,4), (3,5)) +ArraySeq((1,5), (2,5), (3,5)) +ArraySeq((1,5), (2,5), (3,4)) +ArraySeq((1,5), (2,5), (3,4)) +ArraySeq(1, 2) +ArraySeq(a, b) +ArraySeq(1, 2) +ArraySeq(a, b) +ArraySeq(x, y) +ArraySeq(1, 2, 3, 0, 0, 0) +ArraySeq(1, 2, 3) +ArraySeq() +ArraySeq() +ArraySeq(1, 2, 3) +ArraySeq(1, 6, 7, 8, 9) +List(ArraySeq(1, 2, 3), ArraySeq(1, 3, 2), ArraySeq(2, 1, 3), ArraySeq(2, 3, 1), ArraySeq(3, 1, 2), ArraySeq(3, 2, 1)) +6 +6 +List(1, 2, 3) +List(3, 2, 1) +true +false +1 +0 +-1 +-1 +1 +List(ArraySeq(1, 2), ArraySeq(2, 3)) +List(ArraySeq(5, 4, 5), ArraySeq(5, 6)) +ArraySeq(6, 5, 5, 4) +true +true +1 +2 +3 +ArraySeq(1, 2, 3) +ArraySeq((1,0), (2,1), (3,2)) +List(1, 2, 3) +Vector(1, 2, 3) +ArrayBuffer(1, 2, 3) +ArraySeq(1, 2, 3) +ArraySeq(1, 2, 3) +List(1, 2, 3) +Set(1, 2, 3) +Vector(1, 2, 3) +ArrayView(1, 2, 3) +Map(1 -> 5, 2 -> 4, 3 -> 5) +Map(1 -> 5, 2 -> 4, 3 -> 5) +ArraySeq() +true +false +false +ArraySeq(1, 2, 2, 3) +Found(1) +ArraySeq(1, 3) +(2,4) +(2,6) +(3,4) +(3,6) +ArraySeq((2,4), (2,6), (3,4), (3,6)) +ArraySeq() +ArraySeq(ArraySeq(1, 4), ArraySeq(2, 5), ArraySeq(3, 6)) +false +ArraySeq(a, b) +ArraySeq(1, 2, 4, 1, 2, 3, 9, 10) +List((1,5), (1,4), (1,5), (1,6), (1,5), (1,4), (1,5), (1,6), (1,5), (1,4), (1,5), (1,6)) +List((1,true,1,2,3,4,5.0,6.0,a,abc,xyz,())) +ArraySeq((1,true,1,2,3,4,5.0,6.0,a,abc,xyz,())) diff --git a/tests/run/IArrayOps.scala b/tests/run/IArrayOps.scala new file mode 100644 index 000000000000..81a6e3c2a11b --- /dev/null +++ b/tests/run/IArrayOps.scala @@ -0,0 +1,280 @@ +@main def Test: Unit = + val iarr1 = IArray(1, 2, 3) + val iarr2 = IArray(5, 4, 5, 6) + + println(iarr1.toSeq) + println(iarr1.contains(1)) + println(iarr1.contains(4)) + println(iarr1.updated(1, 9).toSeq) + println(iarr1.updated(1, "a").toSeq) + + val arr = Array(0, 0, 0, 0) + iarr1.copyToArray(arr) + println(arr.toSeq) + iarr1.copyToArray(arr, 1) + println(arr.toSeq) + iarr2.copyToArray(arr, 1, 2) + println(arr.toSeq) + + println(arr.count(_ == 1)) + println(arr.count(_ <= 2)) + + println(arr.drop(0).toSeq) + println(arr.drop(1).toSeq) + println(arr.drop(6).toSeq) + + println((iarr1 ++ iarr2).toSeq) + println((iarr1 ++ iarr2.toSeq).toSeq) + println((iarr1 :+ 7).toSeq) + println((8 +: iarr1).toSeq) + println((iarr1 :++ iarr2).toSeq) + println((iarr2 :++ List(12, 13, 14)).toSeq) + println((List(12, 13, 14) ++: iarr2).toSeq) + + val sb = StringBuilder() + iarr1.addString(sb).append("\n") + iarr1.addString(sb, "-").append("\n") + iarr1.addString(sb, "(", ",", ")") + println(sb) + + println(iarr1.appended(5).toSeq) + println(iarr1.appendedAll(iarr2).toSeq) + println(iarr1.appendedAll(List(1, 4)).toSeq) + println(iarr1.prepended(5).toSeq) + println(iarr1.prependedAll(List(5, 6)).toSeq) + + println(iarr1.collect { case x if x % 2 == 1 => 2 * x }.toSeq) + println(iarr1.collectFirst { case x if x % 2 == 1 => 2 * x }) + + println(iarr1.combinations(1).map(_.toSeq).toSeq) + println(iarr1.combinations(2).map(_.toSeq).toSeq) + println(iarr1.combinations(3).map(_.toSeq).toSeq) + + println(iarr1.concat(iarr2).toSeq) + println(iarr1.concat(List(8, 9)).toSeq) + println(iarr1.containsSlice(iarr2)) + println(iarr1.containsSlice(List(2, 3))) + + println(iarr1.corresponds(iarr2)(_ == _)) + println(iarr1.corresponds(List(1, 2, 3))(_ == _)) + println(iarr1.corresponds(List(2, 4, 6))(_ == 2 * _)) + + println(iarr1.diff(List(1, 2)).toSeq) + println(iarr1.diff(IArray(1, 2)).toSeq) + + println(iarr1.distinct.toSeq) + println(iarr2.distinct.toSeq) + println(iarr2.distinctBy(_ % 2 == 1).toSeq) + + println(iarr1.startsWith(IArray(2, 3))) + println(iarr1.startsWith(List(2, 3))) + println(iarr1.endsWith(IArray(2, 3))) + println(iarr1.endsWith(List(2, 3))) + println(iarr1.findLast(_ <= 1)) + println(iarr1.findLast(_ <= 2)) + + println(iarr1.fold(0)(_ + _)) + println(iarr1.foldLeft(0)(_ + _)) + println(iarr1.foldRight(0)(_ + _)) + + println(iarr1.reduce(_ + _)) + println(iarr1.reduceLeft(_ + _)) + println(iarr1.reduceRight(_ + _)) + + println(iarr1.groupBy(identity).mapValues(_.toSeq).toMap) + println(iarr1.groupBy(_ % 2).mapValues(_.toSeq).toMap) + + println(iarr1.groupMap(identity)(_.toString).mapValues(_.toSeq).toMap) + println(iarr1.groupMap(_ % 2)(_.toString).mapValues(_.toSeq).toMap) + + println(iarr1.groupMapReduce(identity)(_.toString)(_ + _).mapValues(_.toSeq).toMap) + println(iarr1.groupMapReduce(_ % 2)(_.toString)(_ + _).mapValues(_.toSeq).toMap) + + println(iarr1.grouped(2).map(_.toSeq).toList) + + println(iarr1.indexOfSlice(IArray(1, 2))) + println(iarr1.indexOfSlice(List(2, 3))) + println(iarr1.indexOfSlice(IArray(1, 2), 1)) + println(iarr1.indexOfSlice(List(2, 3), 1)) + println(iarr1.lastIndexOfSlice(IArray(1, 2))) + println(iarr1.lastIndexOfSlice(List(2, 3))) + println(iarr1.lastIndexOfSlice(IArray(1, 2), 1)) + println(iarr1.lastIndexOfSlice(List(2, 3), 1)) + + println(iarr1.inits.map(_.toSeq).toList) + println(iarr1.tails.map(_.toSeq).toList) + println(iarr1.intersect(List(1, 2)).toSeq) + println(iarr1.intersect(List(2, 3)).toSeq) + println(iarr1.isTraversableAgain) + println(iarr1.knownSize) + println(iarr1.lazyZip(iarr2)) + println(iarr1.lazyZip(iarr2.toSeq).toList) + println(iarr1.lengthCompare(3)) + println(iarr1.lengthCompare(1)) + println(iarr1.lengthCompare(4)) + + println(iarr1.max) + println(iarr1.maxOption) + println(iarr1.maxBy(identity)) + println(iarr1.maxByOption(identity)) + println(iarr1.min) + println(iarr1.minOption) + println(iarr1.minBy(identity)) + println(iarr1.minByOption(identity)) + + println(iarr1.mkString) + println(iarr1.mkString("-")) + println(iarr1.mkString("(", ",", ")")) + + println(iarr1.zip(iarr2.toSeq).toSeq) + println(iarr1.zip(Iterator(5, 5, 5)).toSeq) + println(iarr1.zipAll(IArray(5, 5), 3, 4).toSeq) + println(iarr1.zipAll(List(5, 5), 3, 4).toSeq) + + println(IArray((1, 'a'), (2, 'b')).unzip._1.toSeq) + println(IArray((1, 'a'), (2, 'b')).unzip._2.toSeq) + println(IArray((1, 'a', "x"), (2, 'b', "y")).unzip3._1.toSeq) + println(IArray((1, 'a', "x"), (2, 'b', "y")).unzip3._2.toSeq) + println(IArray((1, 'a', "x"), (2, 'b', "y")).unzip3._3.toSeq) + + println(iarr1.padTo(6, 0).toSeq) + println(iarr1.partitionMap[Int, Int](i => Left(i))._1.toSeq) + println(iarr1.partitionMap[Int, Int](i => Left(i))._2.toSeq) + println(iarr1.partitionMap[Int, Int](i => Right(i))._1.toSeq) + println(iarr1.partitionMap[Int, Int](i => Right(i))._2.toSeq) + println(iarr1.patch(1, List(6, 7, 8, 9), 2).toSeq) + println(iarr1.permutations.map(_.toSeq).toList) + + println(iarr1.sum) + println(iarr1.product) + + println(iarr1.iterator.toList) + println(iarr1.reverseIterator.toList) + + println(iarr1.sameElements(iarr1)) + println(iarr1.sameElements(iarr2.toSeq)) + + println(iarr1.segmentLength(_ < 2)) + println(iarr1.segmentLength(_ < 2, 1)) + + println(iarr1.sizeCompare(iarr2)) + println(iarr1.sizeCompare(iarr2.toSeq)) + println(iarr1.sizeCompare(1)) + + println(iarr1.sliding(2).map(_.toSeq).toList) + println(iarr2.sliding(3, 2).map(_.toSeq).toList) + + println(iarr2.sortBy(i => -i).toSeq) + + println(iarr1.startsWith(Iterator(1, 2), 0)) + println(iarr1.startsWith(Iterator(2, 3), 1)) + + println(iarr1.tapEach(x => println(x)).toSeq) + + println(iarr1.zipWithIndex.toSeq) + + println(iarr1.to(List)) + println(iarr1.to(Vector)) + println(iarr1.toBuffer) + println(iarr1.toIndexedSeq) + println(iarr1.toIterable) + println(iarr1.toList) + println(iarr1.toSet) + println(iarr1.toVector) + println(iarr1.view) + println(iarr1.zip(iarr2).toMap) + println(iarr1.zip(iarr2.toSeq).toMap) + + println(iarr1.empty) + println(iarr1.isTraversableAgain) + println(iarr1.lengthIs < 2) + println(iarr1.sizeIs < 2) + + iarr1.stepper + + println(IArray(List(1, 2), List(2, 3)).flatten.toSeq) + + println(iarr1.search(2)) + + println(iarr1.withFilter(_ != 2).map(identity).toSeq) + + for + x <- iarr1 + if x != 1 + y <- iarr2 + if y != 5 + if y != 65 + do + println((x, y)) + + println( + (for + x <- iarr1 + if x != 1 + y <- iarr2.toSeq + if y != 5 + if y != 65 + yield + (x, y) + ).toSeq) + + println(IArray[IArray[Int]]().transpose.map(_.toSeq).toSeq) + println(IArray(IArray(1, 2, 3), IArray(4, 5, 6)).transpose.map(_.toSeq).toSeq) + + println(IArray.equals(IArray("a"), IArray("b"))) + println(IArray.from(List("a", "b")).toSeq) + + val iab = IArray.newBuilder[Int] + iab += 1 + iab += 2 + iab.addOne(4) + iab.addAll(iarr1) + iab.addAll(Array(9)) + iab.addAll(Seq(10)) + println(iab.result().toSeq) + + + println( + (for + x <- List(1) + y <- iarr1 + y <- iarr2 + yield + (x, y) + ).toSeq) + + println( + (for + x1 <- List(1) + x2 <- IArray(true) + x3 <- IArray(1: Byte) + x4 <- IArray(2: Short) + x5 <- IArray(3) + x6 <- IArray(4L) + x7 <- IArray(5f) + x8 <- IArray(6d) + x9 <- IArray('a') + x10 <- IArray("abc") + x11 <- IArray("xyz": Any) + x12 <- IArray(()) + yield + (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + ).toSeq) + + println( + (for + x1 <- IArray(1) + x2 <- IArray(true) + x3 <- IArray(1: Byte) + x4 <- IArray(2: Short) + x5 <- IArray(3) + x6 <- IArray(4L) + x7 <- IArray(5f) + x8 <- IArray(6d) + x9 <- IArray('a') + x10 <- IArray("abc") + x11 <- IArray("xyz": Any) + x12 <- IArray(()) + yield + (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) + ).toSeq)