Abstract supertype of categories whose
elements may be iterated. Iterable categories are often
called streams. A stream is a source of Iterator
s,
which produce the elements of the stream. A given element
may occur more than once in a stream, that is, it may be
produced more than once by a given iterator of the stream.
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 finite stream is a stream whose iterators are
exhaustible, that is, they eventually stop producing
elements. 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. It is possible for a given element to occur
a (countably) infinite number of times in a nonfinite
stream. It may not, in general, be possible to even
determine if an insteance of Iterable
is finite.
For a nonfinite stream, certain operations of this
interface either never terminate or result in an
AssertionError
.
A stream may be mutable, in which case two distinct iterators for the stream might not produce exactly the same elements. Furthermore, even an immutable 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 distinct iterators of the stream.
However, a stream has a well-defined set of elements, and
so 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 total number of
elements, which must be the size
of the stream. For
an immutable nonfinite stream, every element returned by
a given iterator must eventually be returned by any other
iterator of the stream.
A stream may be known to be nonempty:
Iterable<Element,Null>
, usually abbreviated
{Element*}
, represents a possibly-empty stream.Iterable<Element,Nothing>
, usually
abbreviated {Element+}
, represents a nonempty stream.Every iterator for a nonempty stream must produce at least one element.
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
and its subtypes, Iterable
does
not define nor require any form of
value equality, and some streams simply
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 the elements of two streams, taking order into
account, use the function corresponding()
.
{Float*} xs = ... ; {Float*} ys = ... ; Boolean same = corresponding(xs, ys);
Collection
, corresponding()
, Iterator
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() Since 1.2.0 |
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
Since 1.1.0 |
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. If this stream has exactly one element, the resulting stream is empty. 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 If this is a stream with an unstable iteration order, the resulting stream produces a different set of pairs each time it is iterated, thus violating the general contract for an immutable finite stream. This is a lazy operation and the resulting stream reflects changes to this stream. Since 1.1.0 |
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+]|[]&Iterable<Result,Absent> 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 Since 1.2.0 |
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 is not null and
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 is not null and
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() Since 1.1.0 |
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() Since 1.1.0 |
frequencies | Source Codeshared Map<Element&Object,Integer> frequencies() Produce a For example: "helloworld".frequencies() produces the map
This is an eager operation, and the resulting map does not reflect changes to this stream. Since 1.2.0 |
getFromFirst | Source Codeshared default Element? getFromFirst(Integer index) The Since 1.1.0 |
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() Since 1.2.0 |
indexes | Source Codeshared default Range<Integer>|[] indexes() A Since 1.2.0 |
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 This is a lazy operation and the resulting stream reflects changes to this stream. Parameters:
Throws
See also interleave() Since 1.1.0 |
iterator | Source Codeshared formal Iterator<Element> iterator() An iterator for the elements belonging to this stream. If this is a nonempty stream with type |
locate | Source Codeshared default <Integer->Element&Object>? locate(Boolean selecting(Element&Object element)) The first element of this stream which is not null and
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() Since 1.2.0 |
locateLast | Source Codeshared default <Integer->Element&Object>? locateLast(Boolean selecting(Element&Object element)) The last element of this stream which is not null and
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() Since 1.2.0 |
locations | Source Codeshared default {<Integer->Element&Object>*} locations(Boolean selecting(Element&Object element)) A stream producing all elements of this stream which are not null and 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() Since 1.2.0 |
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 See also max() , min() , byIncreasing() , byDecreasing() , comparing Since 1.1.0 |
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 Since 1.2.0 |
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 If this is a stream with an unstable iteration order, the resulting stream produces a different set of pairs each time it is iterated, thus violating the general contract for an immutable finite stream. This is a lazy operation and the resulting stream reflects changes to this stream. Parameters:
Throws
Since 1.1.0 |
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
Since 1.1.0 |
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() Since 1.1.0 |
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 If this is a stream with an unstable iteration order, the elements of the resulting stream do not occur in repeating order. This is a lazy operation and the resulting stream reflects changes to this 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 This is a lazy operation and the resulting stream reflects changes to this stream. Parameters:
See also fold() Since 1.1.0 |
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+]|[]&Iterable<Element,Absent> 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. If this stream is known to be nonempty, that is, if it
is an instance of [String+] bits = "hello world".split().sequence(); Since 1.1.0 |
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() Since 1.1.0 |
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() Since 1.1.0 |
sort | Source Codeshared default [Element+]|[]&Iterable<Element,Absent> 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() , comparing , sort() |
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 } Since 1.1.0 |
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]) (([sum, product], i) => [sum+i, product*i])) This is an eager operation, and the resulting map does not reflect changes to this stream. Parameters:
Since 1.2.0 |
tabulate | Source Codeshared Map<Element&Object,Result> tabulate<Result>(Result collecting(Element key)) Produces a For example: (1..5).tabulate(2.divides) produces the map
This is an eager operation, and the resulting map does not reflect changes to this stream. Parameters:
Since 1.2.0 |
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() Since 1.1.0 |
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() Since 1.1.0 |
Inherited Methods |
Methods inherited from: Object |
Methods inherited from: Category<Element> |