Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
"""Abstract supertype of [[categories|Category]] 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`, usually abbreviated
`{Element*}`, represents a possibly-empty iterable
container. The type `Iterable`, 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 return a *view* of the receiving
iterable object. If the underlying iterable object is
mutable, then changes to the underlying object will be
reflected in the resulting view. Lazy operations are
usually efficient, avoiding memory allocation or
iteration of the receiving iterable object.
- _Eager_ operations return an immutable object. If the
receiving iterable object is mutable, changes to this
object will not be reflected in the resulting immutable
object. Eager operations are often expensive, involving
memory allocation and iteration of the receiving
iterable object.
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:
- sorting operations, for example [[sort]], which are
eager by nature,
- operations which result in a subset or subrange of the
receiving stream, where structural sharing would or
could result in unnecessary memory retention.
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|Sequential]]. 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|Object.equals]], 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);"""
see (`interface Collection`, `function corresponding`)
by ("Gavin")
tagged("Streams")
shared interface Iterable
satisfies Category<>
given Absent satisfies Null {
"An iterator for the elements belonging to this stream."
shared formal Iterator iterator();
"Returns `true` if the iterator for this stream produces
the given element, or `false` otherwise. In the case of
an infinite stream, this operation might never terminate;
furthermore, this default implementation iterates all
the elements until found (or not), which might be very
expensive."
shared actual default Boolean contains(Object element)
=> any((e) => if (exists e) then e==element else false);
"Determines if the stream is empty, that is to say, if
the iterator returns no elements."
shared default Boolean empty
=> iterator().next() is Finished;
"The number of elements returned by the [[iterator]] of
this stream, if the iterator terminates. In the case of
an infinite stream, this operation never terminates."
shared default Integer size => count((e) => true);
"Determines if this stream has more elements than the
given [[length]]. This is an efficient operation for
streams with many elements."
see (`value size`)
shared default Boolean longerThan(Integer length) {
if (length<0) {
return true;
}
variable value count=0;
for (element in this) {
if (count++==length) {
return true;
}
}
return false;
}
"Determines if this stream has fewer elements than the
given [[length]]. This is an efficient operation for
streams with many elements."
see (`value size`)
shared default Boolean shorterThan(Integer length) {
if (length<=0) {
return false;
}
variable value count=0;
for (element in this) {
if (++count==length) {
return false;
}
}
return true;
}
"The first element returned by the iterator, if any, or
`null` if this stream is empty. For a stream with an
unstable iteration order, a different value might be
produced each time `first` is evaluated."
shared default Absent|Element first {
if (!is Finished first = iterator().next()) {
return first;
}
else {
"iterator for nonempty iterable must produce at
least one element"
assert (is Absent null);
return null;
}
}
"The last element returned by the iterator, if any, or
`null` if this stream is empty. In the case of an
infinite stream, this operation never terminates;
furthermore, this default implementation iterates all
elements, which might be very expensive."
shared default Absent|Element last {
variable Absent|Element e = first;
for (x in this) {
e = x;
}
return e;
}
"The [[index]]th element returned by an iterator of this
stream, or `null` if there are fewer than `index+1`
elements in the stream. For a stream with an unstable
iteration order, a different value might be produced
each time `getFromFirst(index)` is called for a given
integer `index`."
shared default Element? getFromFirst(Integer index) {
variable value current = 0;
for (element in this) {
if (current++==index) {
return element;
}
}
else {
return null;
}
}
"A [[sequence|Sequential]] 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."
shared default Element[] sequence()
=> let (array = Array(this))
if (array.empty)
then []
else ArraySequence(array);
"A [[Range]] containing all indexes of this stream, or
`[]` if this list is empty. The resulting range is
equal to `0:size`."
shared default Range|[] indexes() => 0:size;
"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 `rest`
is evaluated.
Therefore, if the stream `i` has an unstable iteration
order, the stream `{ i.first, *i.rest }` might not have
the same elements as `i`."
see (`value first`)
shared default {Element*} rest => skip(1);
"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
`exceptLast` is evaluated."
shared default {Element*} exceptLast
=> object satisfies {Element*} {
iterator()
=> let (iter = outer.iterator())
object satisfies Iterator {
variable value current = iter.next();
shared actual Element|Finished next() {
if (!is Finished next = iter.next()) {
value result = current;
current = next;
return result;
}
else {
return finished;
}
}
};
};
"Call the given [[function|step]] 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` loop:
for (word in words) {
print(word.lowercased);
print(word.uppercased);
}
_For certain streams this method is highly efficient,
surpassing the performance of `for` loops on the JVM.
Thus, `each()` is sometimes preferred in highly
performance-critical low-level code._"
shared default void each(
"The function to be called for each element in the
stream."
void step(Element element)) {
for (element in this) {
step(element);
}
}
"Produces a stream containing the results of applying
the given [[mapping|collecting]] to the elements of
this stream.
For any empty stream, `map()` returns an empty stream:
{}.map(f) == {}
For any nonempty stream `it`, and mapping function `f`,
the result of `map()` may be obtained according to this
recursive definition:
it.map(f).first == f(it.first)
it.map(f).rest == it.rest.map(f)
Alternatively, and in practice, `map()` may be defined
by this comprehension:
it.map(f) == { for (e in it) f(e) }
For example, the expression
(0..4).map(10.power)
results in the stream `{ 1, 10, 100, 1000, 10000 }`."
see (`function collect`)
shared default
Iterable map(
"The mapping to apply to the elements."
Result collecting(Element element))
=> { for (elem in this) collecting(elem) };
"Given a [[mapping function|collecting]] that accepts an
[[Element]] and returns a stream of [[Result]]s,
produces a new stream containing all elements of every
`Result` stream that results from applying the function
to the elements of this stream.
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.pair)
produces this stream:
{ \"hello\", \"hola\", \"world\", \"mundo\" }"
see (`function expand`)
shared default
Iterable
flatMap(
"The mapping function to apply to the elements of
this stream, that produces a new stream of
[[Result]]s."
Iterable collecting(Element element))
given OtherAbsent satisfies Null
=> expand(map(collecting));
"Produces a stream containing the elements of this
stream that satisfy the given [[predicate
function|selecting]].
For any empty stream, `filter()` returns an empty
stream:
{}.filter(p) == {}
For any nonempty stream `it`, and predicate `p`, the
result of `filter()` may be obtained according to this
recursive definition:
it.filter(p) == { if (p(it.first)) it.first }.chain(it.rest.filter(f))
Alternatively, and in practice, `filter()` may be
defined by this comprehension:
it.filter(p) == { for (e in it) if (p(e)) e };
For example, the expression
(1..100).filter(13.divides)
results in the stream `{ 13, 26, 39, 52, 65, 78, 91 }`."
see (`function select`)
shared default
{Element*} filter(
"The predicate the elements must satisfy. The
elements which satisfy the predicate are included
in the resulting stream."
Boolean selecting(Element element))
=> { for (elem in this) if (selecting(elem)) elem };
"Produces a stream containing the elements of this
stream that are instances of the given [[type|Type]].
For example, the expression
{ 1, 2, null, 3 }.narrow