1
1
package scala
2
2
import reflect .ClassTag
3
3
4
- import scala .collection .immutable
4
+ import scala .collection ._
5
+ import scala .collection .mutable .Buffer
5
6
6
7
opaque type IArray [+ T ] = Array [_ <: T ]
7
8
@@ -39,15 +40,10 @@ object IArray:
39
40
extension (arr : IArray [Object ]) def length : Int = arr.asInstanceOf [Array [Object ]].length
40
41
extension [T ](arr : IArray [T ]) def length : Int = arr.asInstanceOf [Array [T ]].length
41
42
42
- /** Returns this array concatenated with the given array. */
43
- extension [T ](arr : IArray [T ]) def ++ [U >: T : ClassTag ](that : IArray [U ]): IArray [U ] =
44
- genericArrayOps(arr) ++ that
45
43
46
44
/** Tests whether this array contains a given value as an element. */
47
45
extension [T ](arr : IArray [T ]) def contains (elem : T ): Boolean =
48
- // `genericArrayOps(arr).contains(elem)` does not work because `elem` does not have type `arr.T`
49
- // but we can use `exists` instead, which is how `ArrayOps#contains` itself is implemented:
50
- genericArrayOps(arr).exists(_ == elem)
46
+ genericArrayOps(arr).contains(elem.asInstanceOf )
51
47
52
48
/** Copy elements of this array to another array. */
53
49
extension [T ](arr : IArray [T ]) def copyToArray [U >: T ](xs : Array [U ]): Int =
@@ -100,7 +96,7 @@ object IArray:
100
96
101
97
/** Flattens a two-dimensional array by concatenating all its rows
102
98
* into a single array. */
103
- extension [T ](arr : IArray [T ]) def flatten [U : ClassTag ](using T => Iterable [U ]): IArray [U ] =
99
+ extension [T ](arr : IArray [T ]) def flatten [U ](using asIterable : T => Iterable [ U ], ct : ClassTag [U ]): IArray [U ] =
104
100
genericArrayOps(arr).flatten
105
101
106
102
/** Folds the elements of this array using the specified associative binary operator. */
@@ -135,9 +131,6 @@ object IArray:
135
131
136
132
/** Finds index of first occurrence of some value in this array after or at some start index. */
137
133
extension [T ](arr : IArray [T ]) def indexOf (elem : T , from : Int = 0 ): Int =
138
- // `asInstanceOf` needed because `elem` does not have type `arr.T`
139
- // We could use `arr.iterator.indexOf(elem, from)` or `arr.indexWhere(_ == elem, from)`
140
- // but these would incur some overhead.
141
134
genericArrayOps(arr).indexOf(elem.asInstanceOf , from)
142
135
143
136
/** Finds index of the first element satisfying some predicate after or at some start index. */
@@ -170,7 +163,6 @@ object IArray:
170
163
171
164
/** Finds index of last occurrence of some value in this array before or at a given end index. */
172
165
extension [T ](arr : IArray [T ]) def lastIndexOf (elem : T , end : Int = arr.length - 1 ): Int =
173
- // see: same issue in `indexOf`
174
166
genericArrayOps(arr).lastIndexOf(elem.asInstanceOf , end)
175
167
176
168
/** Finds index of last element satisfying some predicate before or at given end index. */
@@ -236,10 +228,6 @@ object IArray:
236
228
extension [T ](arr : IArray [T ]) def splitAt (n : Int ): (IArray [T ], IArray [T ]) =
237
229
genericArrayOps(arr).splitAt(n)
238
230
239
- /** Tests whether this array starts with the given array. */
240
- extension [T ](arr : IArray [T ]) def startsWith [U >: T ](that : IArray [U ], offset : Int = 0 ): Boolean =
241
- genericArrayOps(arr).startsWith(that)
242
-
243
231
/** The rest of the array without its first element. */
244
232
extension [T ](arr : IArray [T ]) def tail : IArray [T ] =
245
233
genericArrayOps(arr).tail
@@ -260,15 +248,133 @@ object IArray:
260
248
extension [T ](arr : IArray [T ]) def toArray : Array [T ] =
261
249
arr.clone.asInstanceOf [Array [T ]]
262
250
263
- /** Converts an array of pairs into an array of first elements and an array of second elements. */
264
- extension [U : ClassTag , V : ClassTag ](arr : IArray [(U , V )]) def unzip : (IArray [U ], IArray [V ]) =
265
- genericArrayOps(arr).unzip
266
-
267
- /** Returns an array formed from this array and another iterable collection
268
- * by combining corresponding elements in pairs.
269
- * If one of the two collections is longer than the other, its remaining elements are ignored. */
270
- extension [T ](arr : IArray [T ]) def zip [U ](that : IArray [U ]): IArray [(T , U )] =
271
- genericArrayOps(arr).zip(that)
251
+ extension [T ](arr : IArray [T ])
252
+ def ++ [U >: T : ClassTag ](suffix : IArray [U ]): IArray [U ] = genericArrayOps(arr) ++ suffix.toSeq
253
+ def ++ [U >: T : ClassTag ](suffix : IterableOnce [U ]): IArray [U ] = genericArrayOps(arr) ++ suffix
254
+ def :+ [U >: T : ClassTag ](x : U ): IArray [U ] = genericArrayOps(arr) :+ x
255
+ def :++ [U >: T : ClassTag ](suffix : IArray [U ]): IArray [U ] = genericArrayOps(arr) :++ suffix
256
+ def :++ [U >: T : ClassTag ](suffix : IterableOnce [U ]): IArray [U ] = genericArrayOps(arr) :++ suffix
257
+ def addString (b : mutable.StringBuilder ): mutable.StringBuilder = arr.toSeq.addString(b)
258
+ def addString (b : mutable.StringBuilder , sep : String ): mutable.StringBuilder = arr.toSeq.addString(b, sep)
259
+ def addString (b : mutable.StringBuilder , start : String , sep : String , end : String ): mutable.StringBuilder = arr.toSeq.addString(b, start, sep, end)
260
+ def appended [U >: T : ClassTag ](x : U ): IArray [U ] = genericArrayOps(arr).appended(x)
261
+ def appendedAll [U >: T : ClassTag ](suffix : IArray [U ]): IArray [U ] = genericArrayOps(arr).appendedAll(suffix)
262
+ def appendedAll [U >: T : ClassTag ](suffix : IterableOnce [U ]): IArray [U ] = genericArrayOps(arr).appendedAll(suffix)
263
+ def collect [U : ClassTag ](pf : PartialFunction [T , U ]): IArray [U ] = genericArrayOps(arr).collect(pf)
264
+ def collectFirst [U ](f : PartialFunction [T , U ]): Option [U ] = genericArrayOps(arr).collectFirst(f)
265
+ def combinations (n : Int ): Iterator [IArray [T ]] = genericArrayOps(arr).combinations(n)
266
+ def concat [U >: T : ClassTag ](suffix : IArray [U ]): IArray [U ] = genericArrayOps(arr).concat(suffix)
267
+ def concat [U >: T : ClassTag ](suffix : IterableOnce [U ]): IArray [U ] = genericArrayOps(arr).concat(suffix)
268
+ def containsSlice [U ](that : IArray [U ]): Boolean = arr.toSeq.containsSlice(that.toSeq)
269
+ def containsSlice [U ](that : Seq [U ]): Boolean = arr.toSeq.containsSlice(that)
270
+ def corresponds [U ](that : IArray [U ])(p : (T , U ) => Boolean ): Boolean = arr.toSeq.corresponds(that.toSeq)(p)
271
+ def corresponds [U ](that : IterableOnce [U ])(p : (T , U ) => Boolean ): Boolean = arr.toSeq.corresponds(that)(p)
272
+ def diff [U >: T ](that : IArray [U ]): IArray [T ] = genericArrayOps(arr).diff(that.toSeq)
273
+ def diff [U >: T ](that : Seq [U ]): IArray [T ] = genericArrayOps(arr).diff(that)
274
+ def distinct : IArray [T ] = genericArrayOps(arr).distinct
275
+ def distinctBy [U ](f : T => U ): IArray [T ] = genericArrayOps(arr).distinctBy(f)
276
+ def empty : immutable.ArraySeq [T ] = arr.toSeq.empty
277
+ def startsWith [U >: T ](that : IArray [U ]): Boolean = genericArrayOps(arr).startsWith(that, 0 )
278
+ def startsWith [U >: T ](that : IArray [U ], offset : Int ): Boolean = genericArrayOps(arr).startsWith(that, offset)
279
+ def startsWith [U >: T ](that : IterableOnce [U ]): Boolean = genericArrayOps(arr).startsWith(that, 0 )
280
+ def startsWith [U >: T ](that : IterableOnce [U ], offset : Int ): Boolean = genericArrayOps(arr).startsWith(that, offset)
281
+ def endsWith [U >: T ](that : IArray [U ]): Boolean = genericArrayOps(arr).endsWith(that)
282
+ def endsWith [U >: T ](that : Iterable [U ]): Boolean = genericArrayOps(arr).endsWith(that)
283
+ def findLast (p : T => Boolean ): Option [T ] = arr.toSeq.findLast(p)
284
+ def groupBy [K ](f : T => K ): immutable.Map [K , IArray [T ]] = genericArrayOps(arr).groupBy(f)
285
+ def groupMap [K , U : ClassTag ](key : T => K )(f : T => U ): immutable.Map [K , IArray [U ]] = genericArrayOps(arr).groupMap(key)(f)
286
+ def groupMapReduce [K , U ](key : (T ) => K )(f : (T ) => U )(reduce : (U , U ) => U ): immutable.Map [K , U ] = arr.toSeq.groupMapReduce(key)(f)(reduce)
287
+ def grouped (size : Int ): Iterator [IArray [T ]] = genericArrayOps(arr).grouped(size)
288
+ def indexOfSlice [U >: T ](that : IArray [U ]): Int = arr.toSeq.indexOfSlice(that)
289
+ def indexOfSlice [U >: T ](that : Seq [U ]): Int = arr.toSeq.indexOfSlice(that)
290
+ def indexOfSlice [U >: T ](that : IArray [U ], from : Int ): Int = arr.toSeq.indexOfSlice(that, from)
291
+ def indexOfSlice [U >: T ](that : Seq [U ], from : Int ): Int = arr.toSeq.indexOfSlice(that, from)
292
+ def inits : Iterator [IArray [T ]] = genericArrayOps(arr).inits
293
+ def intersect [U >: T ](that : IArray [U ]): IArray [T ] = genericArrayOps(arr).intersect(that)
294
+ def intersect [U >: T ](that : Seq [U ]): IArray [T ] = genericArrayOps(arr).intersect(that)
295
+ def isTraversableAgain : Boolean = arr.toSeq.isTraversableAgain
296
+ def knownSize : Int = arr.length
297
+ def lastIndexOfSlice [U >: T ](that : IArray [U ]): Int = arr.toSeq.lastIndexOfSlice(that)
298
+ def lastIndexOfSlice [U >: T ](that : Seq [U ]): Int = arr.toSeq.lastIndexOfSlice(that)
299
+ def lastIndexOfSlice [U >: T ](that : IArray [U ], end : Int ): Int = arr.toSeq.lastIndexOfSlice(that, end)
300
+ def lastIndexOfSlice [U >: T ](that : Seq [U ], end : Int ): Int = arr.toSeq.lastIndexOfSlice(that, end)
301
+ def lazyZip [U ](that : IArray [U ]): LazyZip2 [T , U , IArray [T ]] = genericArrayOps(arr).lazyZip[U ](that).asInstanceOf [LazyZip2 [T , U , IArray [T ]]]
302
+ def lazyZip [U ](that : Iterable [U ]): LazyZip2 [T , U , IArray [T ]] = genericArrayOps(arr).lazyZip[U ](that).asInstanceOf [LazyZip2 [T , U , IArray [T ]]]
303
+ def lengthCompare (len : Int ): Int = genericArrayOps(arr).lengthCompare(len)
304
+ def lengthIs : IterableOps .SizeCompareOps = arr.toSeq.lengthIs
305
+ def max [U >: T ](using math.Ordering [U ]): T = arr.toSeq.max[U ]
306
+ def maxBy [U ](f : T => U )(using math.Ordering [U ]): T = arr.toSeq.maxBy(f)
307
+ def maxByOption [U ](f : T => U )(using math.Ordering [U ]): Option [T ] = arr.toSeq.maxByOption(f)
308
+ def maxOption [U >: T ](using math.Ordering [U ]): Option [U ] = arr.toSeq.maxOption[U ]
309
+ def min [U >: T ](using math.Ordering [U ]): T = arr.toSeq.min[U ]
310
+ def minBy [U ](f : T => U )(using math.Ordering [U ]): T = arr.toSeq.minBy(f)
311
+ def minByOption [U ](f : T => U )(using math.Ordering [U ]): Option [T ] = arr.toSeq.minByOption(f)
312
+ def minOption [U >: T ](using math.Ordering [U ]): Option [U ] = arr.toSeq.minOption[U ]
313
+ def mkString : String = arr.toSeq.mkString
314
+ def mkString (sep : String ): String = arr.toSeq.mkString(sep)
315
+ def mkString (start : String , sep : String , end : String ): String = arr.toSeq.mkString(start, sep, end)
316
+ def padTo [U >: T : ClassTag ](len : Int , elem : U ): IArray [U ] = genericArrayOps(arr).padTo(len, elem)
317
+ def partitionMap [T1 : ClassTag , T2 : ClassTag ](f : T => Either [T1 , T2 ]): (IArray [T1 ], IArray [T2 ]) = genericArrayOps(arr).partitionMap(f)
318
+ def patch [U >: T : ClassTag ](from : Int , other : IterableOnce [U ], replaced : Int ): IArray [U ] = genericArrayOps(arr).patch(from, other, replaced)
319
+ def permutations : Iterator [IArray [T ]] = genericArrayOps(arr).permutations
320
+ def prepended [U >: T : ClassTag ](x : U ): IArray [U ] = genericArrayOps(arr).prepended(x)
321
+ def prependedAll [U >: T : ClassTag ](prefix : IterableOnce [U ]): IArray [U ] = genericArrayOps(arr).prependedAll(prefix)
322
+ def product [U >: T ](using math.Numeric [U ]): U = arr.toSeq.product[U ]
323
+ def reduce [U >: T ](op : (U , U ) => U ): U = arr.toSeq.reduce(op)
324
+ def reduceLeft [U >: T ](op : (U , T ) => U ): U = arr.toSeq.reduceLeft(op)
325
+ def reduceRight [U >: T ](op : (T , U ) => U ): U = arr.toSeq.reduceRight(op)
326
+ def reverseIterator : Iterator [T ] = genericArrayOps(arr).reverseIterator
327
+ def sameElements [U >: T ](that : IArray [U ]): Boolean = arr.toSeq.sameElements(that)
328
+ def sameElements [U >: T ](that : IterableOnce [U ]): Boolean = arr.toSeq.sameElements(that)
329
+ def search [U >: T ](elem : U )(using Ordering [U ]): Searching .SearchResult = arr.toSeq.search(elem)
330
+ def search [U >: T ](elem : U , from : Int , to : Int )(using Ordering [U ]): Searching .SearchResult = arr.toSeq.search(elem, from, to)
331
+ def segmentLength (p : (T ) => Boolean , from : Int ): Int = arr.toSeq.segmentLength(p, from)
332
+ def segmentLength (p : (T ) => Boolean ): Int = arr.toSeq.segmentLength(p)
333
+ def sizeCompare (that : IArray [Any ]): Int = arr.toSeq.sizeCompare(that)
334
+ def sizeCompare (that : Iterable [_]): Int = arr.toSeq.sizeCompare(that)
335
+ def sizeCompare (otherSize : Int ): Int = genericArrayOps(arr).sizeCompare(otherSize)
336
+ def sizeIs : IterableOps .SizeCompareOps = arr.toSeq.sizeIs
337
+ def sliding (size : Int , step : Int = 1 ): Iterator [IArray [T ]] = genericArrayOps(arr).sliding(size, step)
338
+ def stepper [S <: Stepper [_]](using StepperShape [T , S ]): S = genericArrayOps(arr).stepper[S ]
339
+ def sum [U >: T ](using math.Numeric [U ]): U = arr.toSeq.sum[U ]
340
+ def tails : Iterator [IArray [T ]] = genericArrayOps(arr).tails
341
+ def tapEach [U ](f : (T ) => U ): IArray [T ] =
342
+ arr.toSeq.foreach(f)
343
+ arr
344
+ def to [C1 ](factory : Factory [T , C1 ]): C1 = arr.toSeq.to(factory)
345
+ def toBuffer [U >: T ]: Buffer [U ] = arr.toSeq.toBuffer[U ]
346
+ def toIndexedSeq : immutable.IndexedSeq [T ] = arr.toSeq.toIndexedSeq
347
+ def toIterable : Iterable [T ] = arr.toSeq.toIterable
348
+ def toList : List [T ] = arr.toSeq.toList
349
+ def toSet : Set [T ] = arr.toSeq.toSet
350
+ def toVector : Vector [T ] = arr.toSeq.toVector
351
+ def unzip [T1 , T2 ](using asPair : T => (T1 , T2 ), ct1 : ClassTag [T1 ], ct2 : ClassTag [T2 ]): (IArray [T1 ], IArray [T2 ]) = genericArrayOps(arr).unzip
352
+ 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
353
+ def updated [U >: T : ClassTag ](index : Int , elem : U ): IArray [U ] = genericArrayOps(arr).updated(index, elem)
354
+ def view : SeqView [T ] = genericArrayOps(arr).view
355
+ def withFilter (p : T => Boolean ): WithFilter [T ] = new WithFilter (p, arr)
356
+ def zip [U ](that : IArray [U ]): IArray [(T , U )] = genericArrayOps(arr).zip(that)
357
+ def zip [U ](that : IterableOnce [U ]): IArray [(T , U )] = genericArrayOps(arr).zip(that)
358
+ def zipAll [T1 >: T , U ](that : IArray [U ], thisElem : T1 , thatElem : U ): IArray [(T1 , U )] = genericArrayOps(arr).zipAll(that, thisElem, thatElem)
359
+ def zipAll [T1 >: T , U ](that : Iterable [U ], thisElem : T1 , thatElem : U ): IArray [(T1 , U )] = genericArrayOps(arr).zipAll(that, thisElem, thatElem)
360
+ def zipWithIndex : IArray [(T , Int )] = genericArrayOps(arr).zipWithIndex
361
+ end extension
362
+
363
+ extension [T ](arr : IArray [T ])
364
+ def transpose [U ](implicit asArray : T => IArray [U ]): IArray [IArray [U ]] =
365
+ genericArrayOps(arr).transpose(using asArray.asInstanceOf [T => Array [U ]])
366
+
367
+ extension [T , U >: T : ClassTag ](prefix : IterableOnce [T ])
368
+ def ++: (arr : IArray [U ]): IArray [U ] = genericArrayOps(arr).prependedAll(prefix)
369
+
370
+ extension [T , U >: T : ClassTag ](prefix : IArray [T ])
371
+ def ++: (arr : IArray [U ]): IArray [U ] = genericArrayOps(arr).prependedAll(prefix)
372
+
373
+ extension [T , U >: T : ClassTag ](x : T )
374
+ def +: (arr : IArray [U ]): IArray [U ] = genericArrayOps(arr).prepended(x)
375
+
376
+ extension [T1 , T2 ](arr : IArray [(T1 , T2 )])
377
+ def toMap : Map [T1 , T2 ] = arr.toSeq.toMap
272
378
273
379
/** Conversion from IArray to immutable.ArraySeq */
274
380
extension [T ](arr : IArray [T ]) def toSeq : immutable.ArraySeq [T ] =
@@ -363,16 +469,32 @@ object IArray:
363
469
/** An immutable array with given elements. */
364
470
def apply (x : Unit , xs : Unit * ): IArray [Unit ] = Array (x, xs : _* )
365
471
472
+ /** Build an array from the iterable collection.
473
+ *
474
+ * {{{
475
+ * scala> val a = Array.from(Seq(1, 5))
476
+ * val a: Array[Int] = Array(1, 5)
477
+ *
478
+ * scala> val b = Array.from(Range(1, 5))
479
+ * val b: Array[Int] = Array(1, 2, 3, 4)
480
+ * }}}
481
+ *
482
+ * @param it the iterable collection
483
+ * @return an array consisting of elements of the iterable collection
484
+ */
485
+ def from [A : ClassTag ](it : IterableOnce [A ]): Array [A ] =
486
+ Array .from(it)
487
+
488
+ def newBuilder [T ](using t : ClassTag [T ]): scala.collection.immutable.iarray.IArrayBuilder [T ] =
489
+ scala.collection.immutable.iarray.IArrayBuilder .make[T ]
490
+
366
491
/** Concatenates all arrays into a single immutable array.
367
492
*
368
493
* @param xss the given immutable arrays
369
494
* @return the array created from concatenating `xss`
370
495
*/
371
496
def concat [T : ClassTag ](xss : IArray [T ]* ): IArray [T ] =
372
- // `Array.concat` should arguably take in a `Seq[Array[_ <: T]]`,
373
- // but since it currently takes a `Seq[Array[T]]` we have to perform a cast,
374
- // knowing tacitly that `concat` is not going to do the wrong thing.
375
- Array .concat[T ](xss.asInstanceOf [Seq [Array [T ]]]: _* )
497
+ Array .concat[T ](xss.asInstanceOf [immutable.Seq [Array [T ]]]: _* )
376
498
377
499
/** Returns an immutable array that contains the results of some element computation a number
378
500
* of times. Each element is determined by a separate computation.
@@ -391,7 +513,6 @@ object IArray:
391
513
* @param elem the element computation
392
514
*/
393
515
def fill [T : ClassTag ](n1 : Int , n2 : Int )(elem : => T ): IArray [IArray [T ]] =
394
- // We cannot avoid a cast here as Array.fill creates inner arrays out of our control:
395
516
Array .fill(n1, n2)(elem)
396
517
397
518
/** Returns a three-dimensional immutable array that contains the results of some element computation a number
@@ -512,6 +633,17 @@ object IArray:
512
633
*/
513
634
def iterate [T : ClassTag ](start : T , len : Int )(f : T => T ): IArray [T ] = Array .iterate(start, len)(f)
514
635
636
+ /** Compare two arrays per element.
637
+ *
638
+ * A more efficient version of `xs.sameElements(ys)`.
639
+ *
640
+ * @param xs an array of AnyRef
641
+ * @param ys an array of AnyRef
642
+ * @return true if corresponding elements are equal
643
+ */
644
+ def equals (xs : IArray [AnyRef ], ys : IArray [AnyRef ]): Boolean =
645
+ Array .equals(xs.asInstanceOf [Array [AnyRef ]], ys.asInstanceOf [Array [AnyRef ]])
646
+
515
647
/** Returns a decomposition of the array into a sequence. This supports
516
648
* a pattern match like `{ case IArray(x,y,z) => println('3 elements')}`.
517
649
*
@@ -521,4 +653,66 @@ object IArray:
521
653
def unapplySeq [T ](x : IArray [T ]): Array .UnapplySeqWrapper [_ <: T ] =
522
654
Array .unapplySeq(x)
523
655
524
- end IArray
656
+ /** A lazy filtered array. No filtering is applied until one of `foreach`, `map` or `flatMap` is called. */
657
+ class WithFilter [T ](p : T => Boolean , xs : IArray [T ]):
658
+
659
+ /** Apply `f` to each element for its side effects.
660
+ * Note: [U] parameter needed to help scalac's type inference.
661
+ */
662
+ def foreach [U ](f : T => U ): Unit = {
663
+ val len = xs.length
664
+ var i = 0
665
+ while (i < len) {
666
+ val x = xs(i)
667
+ if (p(x)) f(x)
668
+ i += 1
669
+ }
670
+ }
671
+
672
+ /** Builds a new array by applying a function to all elements of this array.
673
+ *
674
+ * @param f the function to apply to each element.
675
+ * @tparam U the element type of the returned array.
676
+ * @return a new array resulting from applying the given function
677
+ * `f` to each element of this array and collecting the results.
678
+ */
679
+ def map [U : ClassTag ](f : T => U ): IArray [U ] = {
680
+ val b = scala.collection.immutable.iarray.IArrayBuilder .make[U ]
681
+ var i = 0
682
+ while (i < xs.length) {
683
+ val x = xs(i)
684
+ if (p(x)) b += f(x)
685
+ i = i + 1
686
+ }
687
+ b.result()
688
+ }
689
+
690
+ /** Builds a new array by applying a function to all elements of this array
691
+ * and using the elements of the resulting collections.
692
+ *
693
+ * @param f the function to apply to each element.
694
+ * @tparam U the element type of the returned array.
695
+ * @return a new array resulting from applying the given collection-valued function
696
+ * `f` to each element of this array and concatenating the results.
697
+ */
698
+ def flatMap [U : ClassTag ](f : T => IterableOnce [U ]): IArray [U ] = {
699
+ val b = scala.collection.immutable.iarray.IArrayBuilder .make[U ]
700
+ var i = 0
701
+ while (i < xs.length) {
702
+ val x = xs(i)
703
+ if (p(x)) b ++= f(xs(i))
704
+ i += 1
705
+ }
706
+ b.result()
707
+ }
708
+
709
+ def flatMap [BS , U ](f : T => BS )(using asIterable : BS => Iterable [U ], m : ClassTag [U ]): IArray [U ] =
710
+ flatMap[U ](x => asIterable(f(x)))
711
+
712
+ /** Creates a new non-strict filter which combines this filter with the given predicate. */
713
+ def withFilter (q : T => Boolean ): WithFilter [T ] = new WithFilter [T ](a => p(a) && q(a), xs)
714
+
715
+ end WithFilter
716
+
717
+
718
+ end IArray
0 commit comments