Common extension methods for all types of Iterables. Supports a fluent query-like syntax.

0.range(100) // [0...99]
    .filterL(isEven) // [0, 2, 4, ... 98]
    .map(Std.string) // ['0', '2', '4', ... '98']
    .maybeLast(); // Some('98')

Static methods

staticall<A>(as:Iterable<A>, predicate:A ‑> Bool):Bool

Returns true if all elements of as satisfy a predicate

[true, true, true].all(isTrue) == true;
[true, false, true].all(isTrue) == false;

staticall2<A, B>(as:Iterable<A>, bs:Iterable<B>, predicate:(A, B) ‑> Bool):Bool

Returns true if corresponding pairs of as and bs satisfy a predicate

[1, 2, 3].all2([1, 2, 3], equals) == true;
[1, 2, 3].all2([4, 2, 0], equals) == false;

staticand(bs:Iterable<Bool>):Bool

Returns true if every element is true or if bs is empty

staticany<A>(as:Iterable<A>):Bool

Returns true if as is not empty

staticanyMatch<A>(as:Iterable<A>, predicate:A ‑> Bool):Bool

Returns true if any element in as matches a predicate
NOTE: This will evaluate as until a match is found or as is exhausted, so be careful with infinite Iterables

staticap<A, B>(fns:Iterable<A ‑> B>, as:Iterable<A>):Iterable<B>

Experimental
Apply a set of functions to each element of as. Can be called repeatedly if the return type is a function.

[ a -> b -> a + b
, a -> b -> a - b
].ap([1, 2])
 .ap([3, 4])

   | --------- a + b  -------- | --------  a - b  ------- |  
== [(1+3), (1+4), (2+3), (2+4), (1-3), (1-4), (2-3), (2-4)]  
== [  4,     5,     5,     6,    -2,    -3,    -1,    -2]

staticappend<A>(as:Iterable<A>, with:Iterable<A>):Iterable<A>

Returns a new Iterable that appends with onto the end of as

[1, 2, 3].append([4, 5, 6]) == [1, 2, 3, 4, 5, 6];

See also:

staticinlineasIterable<A>(a:A, rest:Rest<A>):Iterable<A>

Converts a single element to an Iterable containing that element
TODO: should this return Iterable1?

staticatWrappedIndex<A>(as:Iterable<A>, index:Int):Option<A>

If as has any elements, returns the element at a positive index
Wraps around to the beginning if index is out of bounds

[1, 2, 3].atWrappedIndex(1)     == Some(2);
[1, 2, 3].atWrappedUndex(10)    == Some(2);
[1].atWrappedIndex(100)         == Some(1);
[].atWrappedIndex(1000)         == None;

staticchoice<A>(as:Iterable<A>, genRandom:() ‑> Float):Option<A>

If possible, draws a random element from as, using genRandom as a source of randomness

staticinlinechoiceStd<A>(as:Iterable<A>):Option<A>

If possible, draws a random element from as, using Math.random as a source of randomness

staticinlinecons<A>(a:A, as:Iterable<A>):Iterable<A>

Adds a value to the front of an Iterable

staticcontains<A>(as:Iterable<A>, a:A):Bool

Returns true if a is present in as
NOTE: This will evaluate as until if finds a or as is exhausted,
so be careful with infinite Iterables

staticcount<A>(as:Iterable<A>):Int

Counts the number of elements in as

    *NOTE*: This will fully evaluate `as`, so be careful with infinite `Iterable`s

staticcycle<A>(as:Iterable<A>):Iterable<A>

Infinitely repeats an Iterable

[6, 9].cycle() == [6, 9, 6, 9, 6, ...];

staticdistribute<A, B>(fn:A ‑> Option<Pair<B, A>>, seed:A):Iterable<B>

A lazy unfold operation, which produces an Iterable from an initial seed. The opposite of foldl (which reduces an Iterable to a single value)

(x -> x == 0 
    ? None
    : Some(x.with(x - 1))
).distribute(5)

== [5, 4, 3, 2, 1]

staticelementAt<A>(as:Iterable<A>, index:Int):Option<A>

If possible, returns an element from as at a specified index

[1, 2, 3].elementAt(1)  == Some(2);
[1, 2, 3].elementAt(10) == None;
[].elementAt(100)       == None;

staticempty<A>():SizedIterable<A>

Returns an empty Iterable

staticinlineenumerate<A>(as:Iterable<A>):Iterable<Pair<Int, A>>

An alternative to indexed. Pairs every element of as with its index

staticevery<A>(as:Iterable<A>, n:Int):Iterable<Iterable<A>>

Splits as into chunks of size n
If n <= 0, returns an empty Iterable

staticexcept<A>(as:Iterable<A>, except:A):Iterable<A>

Returns elements of as that are not equal to except

staticexcepts<A>(as:Iterable<A>, except:Iterable<A>):Iterable<A>

Returns elements of as that do not appear in except

staticfilterFMap<A, B>(as:Iterable<A>, predicate:A ‑> Bool, fn:A ‑> Iterable<B>):Iterable<B>

A fused combination of filter and flatMap

staticfilterL<A>(as:Iterable<A>, predicate:A ‑> Bool):Iterable<A>

Returns elements of as that satisfy some predicate

staticfilterMap<A, B>(as:Iterable<A>, predicate:A ‑> Bool, fn:A ‑> B):Iterable<B>

A fused combination of filter and map

staticfirstMatch<A>(as:Iterable<A>, predicate:A ‑> Bool):Option<A>

If possible, returns the first value of as that matches some predicate
NOTE: This will evaluate as until it finds a match or as is exhausted, so be careful with infinite Iterables

staticfirstOrDefault<A>(as:Iterable<A>, genDefault:() ‑> A):A

Returns the first element of as or a default value if as is empty

staticflatMap<A, B>(as:Iterable<A>, fn:A ‑> Iterable<B>):Iterable<B>

Projects each element of as into an Iterable of Bs using fn as a transform, and flattens the results into a single Iterable
This version is lazy

[1, 2, 3].flatMap(x -> x.replicate(3)) == [1, 1, 1, 2, 2, 2, 3, 3, 3];

See also:

staticflatMapS<A, B>(as:Iterable<A>, fn:A ‑> Iterable<B>):Array<B>

Projects each element of as into an Iterable of Bs using fn as a transform, and flattens the results into a single Iterable
This version is strict

[1, 2, 3].flatMapS(x -> x.replicate(3)) == [1, 1, 1, 2, 2, 2, 3, 3, 3];

See also:

staticflatten<A>(ass:Iterable<Iterable<A>>):Iterable<A>

Appends one level of nested Iterables together

[[1, 2, 3], [4, 5, 6], [7, 8, 9]].flatten() == [1, 2, 3, 4, 5, 6, 7, 8, 9];
[].flatten() == [];

staticfoldl<A, B>(as:Iterable<A>, seed:B, fn:(accumulator:B, current:A) ‑> B):B

Applies fn over elements of as using seed as an initial value, reducing an Iterable to a single value. This version is left-associative

[1, 2, 3, 4, 5].foldl(0, (x, y) -> x + y) == 0+1+2+3+4+5 == 15;
[].foldl(0, (x, y) -> x + y) == 0;

NOTE: This may not terminate with an infinite Iterable

See also:

staticfoldr<A, B>(as:Iterable<A>, seed:B, fn:(current:A, accumulator:B) ‑> B):B

Applies fn over elements of as using seed as an initial value, reducing an Iterable to a single value. This version is right-associative

[1, 2, 3, 4, 5].foldl(0, (x, y) -> x + y) == 0+5+4+3+2+1 == 15;
[].foldr(0, (x, y) -> x + y) == 0;

NOTE: This may not terminate with an infinite Iterable

staticindexed<A>(as:Iterable<A>):KeyValueIterable<Int, A>

An alternative to enumerate. Converts a plain Iterable to one that maintains an index for each element.

staticinlineindices():Iterable<Int>

Returns an Iterable containing every Int >= 0
In theory this is infinite; in practice it will overflow MAX_INT

@:nullSafety(Off)staticinit<A>(as:Iterable<A>):Iterable<A>

Returns all elements of as except the last one

staticintercalate<A>(aas:Iterable<Iterable<A>>, separator:Iterable<A>):Iterable<A>

Inserts separator in between Iterables and flattens the result

[[1, 2], [3, 4], [5, 6]].intercalate([0, 0]) == [1, 2, 0, 0, 3, 4, 0, 0, 5, 6];

staticintersperse<A>(as:Iterable<A>, separator:A):Iterable<A>

Returns an Iterable with separator interspersed between every element of as

[1, 2, 3, 4].intersperse(0) == [1, 0, 2, 0, 3, 0, 4];

staticinlineisEmpty<A>(as:Iterable<A>):Bool

Returns true iff as does not have any elements

staticiterate<A>(a:A, fn:A ‑> A):Iterable<A>

Creates an infinite sequence of T values by applying fn to the first value, then to the result of that, then...

iterate(0, add1) == [x, f(x), f(f(x)), f(f(f(x))), ...] == [0, 1, 2, 3, 4, 5, ...];

staticlastMatch<A>(as:Iterable<A>, predicate:A ‑> Bool):Option<A>

If possible, returns the last value of as that matches some predicate
NOTE: This will evaluate as until it finds a match or as is exhausted, so be careful with infinite Iterables

staticmapL<A, B>(as:Iterable<A>, fn:A ‑> B):Iterable<B>

Projects as into an Iterable of Bs using fn as a transform
This version is lazy

[1, 2, 3].mapL(Std.string) == ['1', '2', '3'];

See also:

staticmapMaybes<A, B>(as:Iterable<Option<A>>, transform:A ‑> B):Iterable<B>

A version of mapL that can discard elements. Only Some values are transformed and returned in the output.

staticmapOutcomes<A, B>(as:Iterable<Outcome<A>>, transform:A ‑> B):Iterable<B>

A version of mapL that can discard elements. Only Success values are transformed and returned in the output.

staticmapS<A, B>(as:Iterable<A>, fn:A ‑> B):Array<B>

Projects as into an Iterable of Bs using fn as a transform
This version is strict

[1, 2, 3].mapS(Std.string) == ['1', '2', '3']

See also:

staticmaybeFirst<A>(as:Iterable<A>):Option<A>

Attempts to get the first element of as, if there is one

[a, b, c].maybeFirst() == Some(a);
[].maybeFirst() == None;

staticmaybeLast<A>(as:Iterable<A>):Option<A>

Attempts to get the last element of as, if there is one

[a, b, c].maybeLast() == Some(c);
[].maybeLast() == None;

NOTE: this will not terminate if as is infinite

staticinlinemutate<A>(as:Iterable<A>, mutator:A ‑> Void):Iterable<A>

Calls mutator on every element of as. Essentially a for loop specifically for mutating values

staticmutatei<A>(as:Iterable<A>, mutator:(Int, A) ‑> Void):Iterable<A>

Calls mutator on every element of as and their indices. Essentially a for loop specifically for mutating values

staticinlinenatural():Iterable<Int>

Returns an infinite Iterable of natural numbers

natural() == [1, 2, 3, 4, 5, 6, ...];

staticnonNull<A>(as:Iterable<Null<A>>):Iterable<A>

Returns only the non-null elements of an Iterable

['a', null, 'b', null, 'c'].nonNull() == ['a', 'b', 'c']

staticopposite<A>(as:Iterable<A>):Array<A>

staticorDefault<A>(as:Iterable<A>, whenEmpty:() ‑> Iterable<A>):Iterable<A>

Returns the input Iterable if it has any elements, or some default if empty

staticorDefault1<A>(as:Iterable<A>, whenEmpty:() ‑> Iterable1<A>):Iterable<A>

Returns the input Iterable if it has any elements, or some default if empty The default is required to have at least one element

staticorElse<A>(as:Iterable<A>, genOther:() ‑> Iterable<A>):Iterable<A>

staticorderByAsc<A>(as:Iterable<A>, selector:A ‑> Int):Array<A>

staticorderByDesc<A>(as:Iterable<A>, selector:A ‑> Int):Array<A>

staticpairs<A>(as:Iterable<A>):Iterable<Pair<A, A>>

Common use of zip, useful for comparing an element with the next one

[1, 2, 3, 4].pairs() == [(1, 2), (2, 3), (3, 4)];

staticpartition<A>(as:Iterable<A>, predicate:A ‑> Bool):Pair<Array<A>, Array<A>>

Splits an Iterable into two subarrays based on a predicate

0.iterate(add1).partition(isEven) == ([0, 2, 4, ...], [1, 3, 5, ...]);

TODO: add a lazy version that doesn't evaluate the source list twice

staticpeek<A>(as:Iterable<A>):Option<A>

Peeks at the next element of an Iterable without consuming it

[1, 2, 3].peek() == Some(1);

NOTE This will evaluate the next element, so be careful if evaulation causes side effects

staticproduct<A, B, C>(as:Iterable<A>, bs:Iterable<B>, fn:(A, B) ‑> C):Iterable<C>

Cartesian product of two Iterables
A deck of playing cards could be represented as suits.product(ranks, Card.new)

staticinlinerange(start:Int, count:Int):Iterable<Int>

Returns an Iterable containing a range of numbers between start and start+count

0.range(5) == [0, 1, 2, 3, 4];

staticrepeat<A>(a:A):Iterable<A>

Returns an Iterable where a is infinitely repeated

staticreplicate<A>(a:A, count:Int):SizedIterable<A>

Returns an Iterable where a is repeated count times

staticscan<A, B>(as:Iterable<A>, seed:B, fn:(B, A) ‑> B):Iterable<B>

Applies fn to each element of as, passing an accumulator value through the computation
This version includes the seed as the first element of the output

[0, 1, 2, 3].scan(1, (x, y) -> x + y) == [1, 1, 2, 4, 7];

staticscan_<A, B>(as:Iterable<A>, seed:B, fn:(B, A) ‑> B):Iterable<B>

Applies fn to each element of as, passing an accumulator value through the computation
This version does not include the seed in the output

[0, 1, 2, 3].scan_(1, (x, y) -> x + y) == [1, 2, 4, 7];

staticshuffled<A>(as:Iterable<A>, genRandom:Int ‑> Int):Array<A>

Returns elements of as in a random order, using genRandom as a source of randomness

staticinlineshuffledStd<A>(as:Iterable<A>):Array<A>

Returns elements of as in a random order, using Std.random as a source of randomness

staticskip<A>(as:Iterable<A>, count:Int):Iterable<A>

Returns all of the elements of as after the first count items
If as has <= count items, return empty list

[a, b, c].skip(2) == [c];
[a, b, c].skip(200) == [];

staticskipWhile<A>(as:Iterable<A>, predicate:A ‑> Bool):Iterable<A>

Skips elements of as until they no longer match predicate
If all elements match, returns an empty Iterable

[1, 2, 3, 4].skipWhile(x -> x < 3) == [3, 4];
[1, 2, 3, 4].skipWhile(x -> x > 0) == [];

NOTE: This may not terminate if every element of an infinite Iterable matches the predicate

staticsomes<A>(as:Iterable<Option<A>>):Iterable<A>

Returns all the Some values from a set of Options

staticspan<A>(as:Iterable<A>, predicate:A ‑> Bool):Pair<Iterable<A>, Iterable<A>>

Returns a Pair containing the longest prefix of as that match some predicate and the rest of the Iterable

[1, 2, 3, 4, 1, 2, 3].span(x -> x < 3) == ([1, 2], [3, 4, 1, 2, 3]);

staticsuccesses<A>(as:Iterable<Outcome<A>>):Iterable<A>

Returns all the Success values from a set of Outcomes

staticinlinetail<A>(as:Iterable<A>):Iterable<A>

Return all elements of an Iterable except the first one.
Returns [] if as is empty or only has one element

[1, 2, 3].tail() == [2, 3];
[1].tail() == [];
[].tail() == [];

statictake<A>(as:Iterable<A>, count:Int):Iterable<A>

Returns up to the first count elements of as
If as does not have >= count elements, it returns as many as it can

[a, b, c, d].take(2) == [a, b];
[].take(2) == [];

@:nullSafety(Off)statictakeWhile<A>(as:Iterable<A>, predicate:A ‑> Bool):Iterable<A>

Returns elements from as until one is found that doesn't match predicate

[1, 2, 3, 4, 5, 6].takeWhile(x -> x < 4) == [1, 2, 3];

staticinlinetoArray<A>(as:Iterable<A>):Array<A>

Converts an Iterable into an Array.
NOTE: Since this fully evaluates the Iterable, it may not terminate if as is infinite.

staticzip<A, B, C>(as:Iterable<A>, bs:Iterable<B>):Iterable<Pair<A, B>>

Returns Pairs of values from as and bs. If the two Iterables are not the same length, zip stops at the end of the shorter one

[1, 2, 3].zip(['a', 'b', 'c']) == [(1, 'a'), (2, 'b'), (3, 'c')]  ;
[1, 2, 3].zip([]) == [];

staticzipWith<A, B, C>(as:Iterable<A>, bs:Iterable<B>, transform:(A, B) ‑> C):Iterable<C>

Applies a transform function to corresponsing pairs of elements in as and bs
If the Iterables don't have the same number of elements, zipWith will only apply until it reaches the end of the shorter one

[1, 2, 3].zipWith([4, 5, 6], (x, y) -> x + y) == [1+4, 2+5, 3+6] == [5, 7, 9];