1
0
forked from Mirror/wren

Use deferred execution for Sequence.map and Sequence.where

The methods Sequence.map and Sequence.where are now implemented using
deferred execution. They return an instance of a new Sequence-derived
class that performs the operation while iterating. This has three main
advantages:

* It can be computationally cheaper when not the whole sequence is
  iterated.

* It consumes less memory since it does not store the result in a newly
  allocated list.

* They can work on infinite sequences.

Some disadvantages are:

* Iterating the returned iterator will be slightly slower due to
  the added indirection.

* You should be aware that modifications made to the original sequence
  will affect the returned sequence.

* If you need the result in a list, you now need to call Sequence.list
  on the result.
This commit is contained in:
Thorbjørn Lindeijer
2015-03-28 22:51:50 +01:00
parent a7fafce265
commit a8ea2a91a6
9 changed files with 160 additions and 44 deletions

View File

@ -26,21 +26,9 @@ class Sequence {
return result
}
map(f) {
var result = new List
for (element in this) {
result.add(f.call(element))
}
return result
}
map(transformation) { new MapSequence(this, transformation) }
where(f) {
var result = new List
for (element in this) {
if (f.call(element)) result.add(element)
}
return result
}
where(predicate) { new WhereSequence(this, predicate) }
all(f) {
for (element in this) {
@ -100,6 +88,32 @@ class Sequence {
}
}
class MapSequence is Sequence {
new(seq, f) {
_seq = seq
_f = f
}
iterate(n) { _seq.iterate(n) }
iteratorValue(iterator) { _f.call(_seq.iteratorValue(iterator)) }
}
class WhereSequence is Sequence {
new(seq, f) {
_seq = seq
_f = f
}
iterate(n) {
while (n = _seq.iterate(n)) {
if (_f.call(_seq.iteratorValue(n))) break
}
return n
}
iteratorValue(iterator) { _seq.iteratorValue(iterator) }
}
class String is Sequence {
bytes { new StringByteSequence(this) }
}