Abstract supertype of categories whose elements may be iterated. Iterable categories are often called streams. A stream need not be finite, but its elements must be countable. That is, for any given element of the stream, every iterator of the stream must eventually return the element, even if the iterator itself is not exhaustible.
A stream may have null elements. That is, an iterator for
the stream may produce the value null
one or more
times. For every non-null element
of a given stream
it
, the expression element in it
must evaluate to
true
. Thus, a stream is a Category
of its non-null
elements.
A given stream might not have a well-defined order, and
so the order in which elements are produced by the
stream's iterator may not be stable. That is, the order
may be different for two different iterators of the
stream. However, a stream has a well-defined set of
elements, and any two iterators for an immutable finite
stream should eventually return the same elements.
Furthermore, any two iterators for an immutable finite
stream should eventually return exactly the same number
of elements, which must be the size
of the stream.
A given stream may not be finite, in which case an
iterator for the stream is never exhaustible, and certain
operations of this interface either never terminate or
result in an AssertionError
. It may not, in general,
be possible to even determine if an Iterable
is finite.
The type Iterable<Element,Null>
, usually abbreviated
{Element*}
, represents a possibly-empty iterable
container. The type Iterable<Element,Nothing>
, usually
abbreviated {Element+}
, represents a nonempty iterable
container.
A value list in braces produces a new instance of
Iterable
:
{String+} words = { "hello", "world" };
An instance of Iterable
may be iterated using a for
loop:
for (c in "hello world") { ... }
Comprehensions provide a convenient syntax for transforming streams:
{Integer+} lengths = { for (w in words) w.size };
The *.
operator may be used to evaluate an attribute
or invoke a method of the elements of the stream,
producing a new stream:
{Integer+} lengths = words*.size;
Iterable
and its subtypes define various operations
that return other iterable objects. Such operations come
in two flavors:
Lazy operations are generally preferred, because they can be efficiently chained. For example:
string.filter((c) => c.letter||c.digit) .map(Character.uppercased)
is much less expensive than:
string.select((c) => c.letter||c.digit) .collect(Character.uppercased)
Furthermore, it is always easy to produce a new immutable iterable object given the view produced by a lazy operation. For example:
[ *string.filter((c) => c.letter||c.digit) .map(Character.uppercased) ]
However, there are certain scenarios where an eager operation is more useful, more convenient, or no more expensive than a lazy operation, including:
sort()
, which are
eager by nature,Certain operations come in both lazy and eager flavors, for example:
map()
vs collect()
,filter()
vs select()
,List.sublist()
vs List.measure()
.Lazy operations normally return an instance of Iterable
,
or even a List
, Map
, or Set
. Eager operations
usually return a sequence. The method
sequence()
materializes the current elements of a
stream into a sequence.
There is no meaningful generic definition of equality for
streams. For some streams—for example,
List
s—order is significant; for others—for
example, Set
s—order is not significant. Therefore,
unlike Collection
, Iterable
does not define or
require any form of value equality, and
some streams do not support value equality. It follows
that the ==
operator should not be used to compare
generic streams, unless the streams are known to share
some additional structure.
To compare two streams, taking order into account, use
the function corresponding()
.
{Float*} xs = ... ; {Float*} ys = ... ; Boolean same = corresponding(xs, ys);
Collection
, corresponding()
no type hierarchy
Attributes | |
coalesced | Source Codeshared default {Element&Object*} coalesced The non-null elements of this stream, in the order in which they occur in this stream. For null elements of the original stream, there is no entry in the resulting stream. For example, the expression { "123", "abc", "456"}.map(parseInteger).coalesced results in the stream See also defaultNullElements() |
cycled | Source Codeshared default Iterable<Element,Absent> cycled An infinite stream that produces the elements of this stream, repeatedly. For example, the expression {6, 9}.cycled.take(5) evaluates to the stream If this stream is empty, the resulting stream also empty. See also repeat() |
distinct | Source Codeshared default Iterable<Element,Absent> distinct A stream that produces every element produced by this stream exactly once. Duplicate elements of this stream are eliminated. Two elements are considered distinct unless they are both null, or unless they are both non-null and equal. For example: String("hello world".distinct) is the string This is a lazy operation and the resulting stream reflects changes to this stream. See also set() |
empty | Source Codeshared default Boolean empty Determines if the stream is empty, that is to say, if the iterator returns no elements. |
exceptLast | Source Codeshared default {Element*} exceptLast A stream containing all but the last element of this
stream. For a stream with an unstable iteration order,
a different stream might be produced each time
|
first | Source Codeshared default Absent|Element first The first element returned by the iterator, if any, or
|
indexed | Source Codeshared default Iterable<Integer->Element,Absent> indexed A stream containing all entries of form
For example, the expression { "hello", null, "world" }.indexed results in the stream See also locations() |
last | Source Codeshared default Absent|Element last The last element returned by the iterator, if any, or
|
paired | Source Codeshared default {Element[2]*} paired A stream containing whose elements are pairs (2-tuples) comprising an element of this stream paired with the next element in the stream. The resulting stream has one fewer elements than this stream. For example, the expression (1..5).paired results in the stream
This expression determines if a stream is monotonically increasing: every { for ([x, y] in nums.paired) x < y } For any stable |
rest | Source Codeshared default {Element*} rest A stream containing all but the first element of this
stream. For a stream with an unstable iteration order,
a different stream might be produced each time Therefore, if the stream See also first |
size | Source Codeshared default Integer size The number of elements returned by the |
string | Source Codeshared actual default String string A string of form Refines Object.string |
Inherited Attributes |
Attributes inherited from: Object |
Methods | |
any | Source Codeshared default Boolean any(Boolean selecting(Element element)) Determines if there is at least one element of this
stream that satisfies the given predicate
function. If the stream is empty, returns
See also every() |
by | Source Codeshared default Iterable<Element,Absent> by(Integer step) Produces a stream containing every For example, the expression (0..10).by(3) results in the stream The step size must be greater than zero. Parameters:
Throws
|
chain | Source Codeshared default Iterable<Element|Other,Absent&OtherAbsent> chain<Other, OtherAbsent>(Iterable<Other,OtherAbsent> other) The elements of this stream, in the order in which they occur in this stream, followed by the elements of the given stream in the order in which they occur in the given stream. For example, the expression (1..3).chain("abc") evaluates to the stream See also expand() |
collect | Source Codeshared default Result[] collect<Result>(Result collecting(Element element)) |
contains | Source Codeshared actual default Boolean contains(Object element) Returns Refines Category.contains |
count | Source Codeshared default Integer count(Boolean selecting(Element element)) Produces the number of elements in this stream that satisfy the given predicate function. For an infinite stream, this method never terminates. |
defaultNullElements | Source Codeshared default Iterable<Element&Object|Default,Absent> defaultNullElements<Default>(Default defaultValue) Produces a stream containing the elements of this
stream, in the order in which they occur in this stream,
after replacing every For example, the expression { "123", "abc", "456" }.map(parseInteger).defaultNullElements(0) results in the stream Parameters:
See also coalesced |
each | Source Codeshared default void each(void step(Element element)) Call the given function for each element of this stream, passing the elements in the order they occur in this stream. For example: words.each((word) { print(word.lowercased); print(word.uppercased); }); Has the same effect as the following for (word in words) { print(word.lowercased); print(word.uppercased); } For certain streams this method is highly efficient,
surpassing the performance of |
every | Source Codeshared default Boolean every(Boolean selecting(Element element)) Determines if all elements of this stream satisfy the
given predicate function. If the stream
is empty, return See also any() |
filter | Source Codeshared default {Element*} filter(Boolean selecting(Element element)) Produces a stream containing the elements of this stream that satisfy the given predicate function. For any empty stream, {}.filter(p) == {} For any nonempty stream it.filter(p) == { if (p(it.first)) it.first }.chain(it.rest.filter(f)) Alternatively, and in practice, it.filter(p) == { for (e in it) if (p(e)) e }; For example, the expression (1..100).filter(13.divides) results in the stream Parameters: See also select() |
find | Source Codeshared default Element? find(Boolean selecting(Element&Object element)) The first element of this stream which satisfies the
given predicate function, if any, or
For example, the expression (-10..10).find(Integer.positive) evaluates to See also findLast() , locate() |
findLast | Source Codeshared default Element? findLast(Boolean selecting(Element&Object element)) The last element of this stream which satisfies the
given predicate function, if any, or
For example, the expression (-10..10).findLast(3.divides) evaluates to See also find() , locateLast() |
flatMap | Source Codeshared default Iterable<Result,Absent|OtherAbsent> flatMap<Result, OtherAbsent>(Iterable<Result,OtherAbsent> collecting(Element element)) Given a mapping function that accepts an
For example, the expression { "Hello", "World" }.flatMap(String.lowercased) results in this stream: { 'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r,' 'l', 'd' } The expression { "hello"->"hola", "world"->"mundo" } .flatMap(Entry<String,String>.pair) produces this stream: { "hello", "hola", "world", "mundo" } Parameters: See also expand() |
fold | Source Codeshared default Result fold<Result>(Result initial)(Result accumulating(Result partial, Element element)) Beginning with a given initial value, apply the given combining function to each element of this stream in turn, progressively accumulating a single result. For an empty stream, {}.fold(z)(f) == z For a given nonempty stream it.fold(z)(f) == f(it.exceptLast.fold(z)(f), it.last) For example, the expression (1..100).fold(0)(plus) results in the integer Parameters:
|
follow | Source Codeshared default {Element|Other+} follow<Other>(Other head) Produces a stream with a given initial element, followed by the elements of this stream, in the order in which they occur in this stream. For example, the expression (1..3).follow(0) evaluates to the stream Note that the expression { head, *stream } See also chain() |
frequencies | Source Codeshared Map<Element&Object,Integer> frequencies() Produce a This is an eager operation, and the resulting map does not reflect changes to this stream. |
getFromFirst | Source Codeshared default Element? getFromFirst(Integer index) The |
group | Source Codeshared Map<Group,[Element+]> group<Group>(Group grouping(Element element)) Classifies the elements of this stream into a new
immutable Within each group, the sequence elements occur in the same order they occurred in this stream. For example: (0..10).group((i) => i.even then “even” else “odd”) produces the map
This is an eager operation, and the resulting map does not reflect changes to this stream. Parameters:
See also summarize() |
indexes | Source Codeshared default Range<Integer>|[] indexes() A |
interpose | Source Codeshared default Iterable<Element|Other,Absent> interpose<Other>(Other element, Integer step = 1) A stream that contains the given For example, the expression String("hello".interpose(' ')) evaluates to the string Parameters:
Throws
See also interleave() |
iterator | Source Codeshared formal Iterator<Element> iterator() An iterator for the elements belonging to this stream. |
locate | Source Codeshared default <Integer->Element&Object>? locate(Boolean selecting(Element&Object element)) The first element of this stream which satisfies the
given predicate function, if any,
together with its position in the stream, or For example, the expression (-10..10).locate(Integer.positive) evaluates to See also locateLast() , locations() , find() , List.firstIndexWhere() |
locateLast | Source Codeshared default <Integer->Element&Object>? locateLast(Boolean selecting(Element&Object element)) The last element of this stream which satisfies the
given predicate function, if any,
together with its position in the stream, or For example, the expression (-10..10).locateLast(3.divides) evaluates to See also locate() , locations() , findLast() , List.lastIndexWhere() |
locations | Source Codeshared default {<Integer->Element&Object>*} locations(Boolean selecting(Element&Object element)) A stream producing all elements of this stream which satisfy the given predicate function, together with their positions in the stream. For example, the expression (-5..5).locations(3.divides) evaluates to the stream Note that this method is more efficient than the
alternative of applying See also locate() , locateLast() , List.indexesWhere() |
longerThan | Source Codeshared default Boolean longerThan(Integer length) |
map | Source Codeshared default Iterable<Result,Absent> map<Result>(Result collecting(Element element)) Produces a stream containing the results of applying the given mapping to the elements of this stream. For any empty stream, {}.map(f) == {} For any nonempty stream it.map(f).first == f(it.first) it.map(f).rest == it.rest.map(f) Alternatively, and in practice, it.map(f) == { for (e in it) f(e) } For example, the expression (0..4).map(10.power) results in the stream See also collect() |
max | Source Codeshared default Element|Absent max(Comparison comparing(Element x, Element y)) Return the largest value in the stream, as measured by
the given comparator function imposing a
partial order upon the elements of the stream, or For example, the expression {-10.0, -1.0, 5.0}.max(byIncreasing(Float.magnitude)) evaluates to For any nonempty stream Note that the toplevel functions |
narrow | Source Codeshared default {Element&Type*} narrow<Type>() Produces a stream containing the elements of this stream that are instances of the given Type. For example, the expression { 1, 2, null, 3 }.narrow<Object>() results in the stream If the type argument |
partition | Source Codeshared default Iterable<[Element+],Absent> partition(Integer length) Produces a stream of sequences of the given For example, the expression "hello".partition(2) results in the stream For any expand { stream.partition(length) } == stream Parameters:
Throws
|
product | Source Codeshared default Iterable<[Element, Other],Absent|OtherAbsent> product<Other, OtherAbsent>(Iterable<Other,OtherAbsent> other) A stream of pairs of elements of this stream and the
the given stream, where for each element For example, this expression (1..3).product("ab") evaluates to the stream
|
reduce | Source Codeshared default Result|Element|Absent reduce<Result>(Result accumulating(Result|Element partial, Element element)) Beginning with the For an empty stream, For a stream with one element, { first }.reduce(f) == first For a given stream it.reduce(f) == f(it.exceptLast.reduce(f), it.last) For example, the expression (1..100).reduce(plus) results in the integer Parameters:
See also fold() |
repeat | Source Codeshared default {Element*} repeat(Integer times) Produces a stream formed by repeating the elements of
this stream the given number of times, or an
empty stream if For example, the expression { 1, 2 }.repeat(3) evaluates to the stream See also cycled |
scan | Source Codeshared default {Result+} scan<Result>(Result initial)(Result accumulating(Result partial, Element element)) The stream of intermediate results obtained by beginning with a given initial value and iteratively applying the given combining function to each element of this stream in turn. For an empty stream, {}.scan(z)(f) == { z } For a given nonempty stream it.scan(z)(f).last == f(it.exceptLast.scan(z)(f).last, it.last) it.scan(z)(f).exceptLast == it.exceptLast.scan(z)(f) The following identities explain the relationship
between it.scan(z)(f).getFromFirst(n) == it.take(n).fold(z)(f) it.scan(z)(f).last == it.fold(z)(f) it.scan(z)(f).first == {}.fold(z)(f) == z For example, the expression (1..4).scan(0)(plus) results in the stream Parameters:
See also fold() |
select | Source Codeshared default Element[] select(Boolean selecting(Element element)) Produce a new sequence containing all elements of this stream that satisfy the given predicate function, in the order in which they occur in this stream. This operation is an eager counterpart to it.select(p) == [*it.filter(p)] See also filter() |
sequence | Source Codeshared default Element[] sequence() A sequence containing all the elements of this stream, in the same order they occur in this stream. This operation eagerly evaluates and collects every element of the stream. |
shorterThan | Source Codeshared default Boolean shorterThan(Integer length) |
skip | Source Codeshared default {Element*} skip(Integer skipping) Produces a stream containing the elements of this
stream, after skipping the first If this stream does not contain more elements than the specified number of elements to skip, the resulting stream has no elements. If the specified number of elements to skip is zero or fewer, the resulting stream contains the same elements as this stream. See also List.sublistFrom() , skipWhile() , take() |
skipWhile | Source Codeshared default {Element*} skipWhile(Boolean skipping(Element element)) Produces a stream containing the elements of this
stream, after skipping the leading elements until the
given predicate function returns Parameters: See also skip() , takeWhile() |
sort | Source Codeshared default Element[] sort(Comparison comparing(Element x, Element y)) Produce a new sequence containing the elements of this stream, sorted according to the given comparator function imposing a partial order upon the elements of the stream. For convenience, the functions For example, this expression "Hello World!".sort(byIncreasing(Character.lowercased)) evaluates to the sequence
This operation is eager by nature. Note that the toplevel function See also increasing() , decreasing() , byIncreasing() , byDecreasing() |
spread | Source Codeshared default Iterable<Result,Absent>(*Args) spread<Result, Args>(Result(*Args) method(Element element)) Given a {Boolean+}(Object) fun = (-1..1).spread(Object.equals); print(fun(0)); //prints { false, true, false } |
summarize | Source Codeshared Map<Group,Result> summarize<Group, Result>(Group grouping(Element element), Result accumulating(Result? partial, Element element)) Efficiently For example, the expression: (1..10) .summarize((i) => i%3, (Integer[2]? pair, i) => if (exists [sum, product] = pair) then [sum+i, product*i] else [i,i]) produces the map
(1..10) .group((i) => i%3) .mapItems((_, item) => item.fold([0,1]) ((pair, i) => let ([sum, product] = pair) [sum+i, product*i])) This is an eager operation, and the resulting map does not reflect changes to this stream. Parameters:
|
tabulate | Source Codeshared Map<Element&Object,Result> tabulate<Result>(Result collecting(Element key)) Produces a This is an eager operation, and the resulting map does not reflect changes to the given stream. Parameters:
|
take | Source Codeshared default {Element*} take(Integer taking) Produces a stream containing the first If the specified number of elements to take is larger than the number of elements of this stream, the resulting stream contains the same elements as this stream. If the specified number of elements to take is fewer than one, the resulting stream has no elements. See also List.sublistTo() , List.initial() , takeWhile() , skip() |
takeWhile | Source Codeshared default {Element*} takeWhile(Boolean taking(Element element)) Produces a stream containing the leading elements of
this stream until the given predicate function
returns Parameters: See also take() , skipWhile() |
Inherited Methods |
Methods inherited from: Object |
Methods inherited from: Category<Element> |