-
-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Iterator#zipLongest and improve zip description #349
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -156,10 +156,40 @@ class Iterator { | |
return new FlatMapIterator(this, mapper, thisArg); | ||
} | ||
|
||
// Creates an iterator that aggregates elements from each of the iterators. | ||
// | ||
// Returns an iterator of Arrays where the i-th tuple contains | ||
// the i-th element from each of the passed iterators. | ||
// The iterator stops when the shortest input iterable is exhausted. | ||
// ...iterators <Array> iterators to be aggregated | ||
// Returns: <Iterator> | ||
zip(...iterators) { | ||
return new ZipIterator(this, iterators); | ||
} | ||
|
||
// Creates an iterator that aggregates elements from each of the iterators. | ||
// | ||
// If the iterables are of uneven length, missing values are filled-in | ||
// with <undefined>. Iteration continues until the longest iterable | ||
// is exhausted. | ||
// ...iterators <Array> iterators to be aggregated | ||
// Returns: <Iterator> | ||
zipLongest(...iterators) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should allow specifying the value that should be used to fill with when there are no values left in one of the iterators. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I couldn't devise a way to make a proper API. |
||
return new ZipIteratorLongest(this, iterators); | ||
} | ||
|
||
// Creates an iterator that aggregates elements from each of the iterators. | ||
// | ||
// If the iterables are of uneven length, missing values are filled-in | ||
// with <defaultValue>. Iteration continues until the longest iterable | ||
// is exhausted. | ||
// defaultValue <any> value to fill-in missing values with | ||
// ...iterators <Array> iterators to be aggregated | ||
// Returns: <Iterator> | ||
zipLongestWith(defaultValue, ...iterators) { | ||
return new ZipIteratorLongest(this, iterators, defaultValue); | ||
} | ||
|
||
chain(...iterators) { | ||
return new ChainIterator(this, iterators); | ||
} | ||
|
@@ -328,14 +358,40 @@ class Iterator { | |
return iter(res && res[Symbol.iterator] ? res : [res]); | ||
} | ||
|
||
// Create iterator by zipping multiple provided iterators into one | ||
// Signature: ...iterators | ||
// iterators <Array> | ||
// Creates an iterator that aggregates elements from each of the iterators. | ||
// | ||
// Returns an iterator of Arrays where the i-th tuple contains | ||
// the i-th element from each of the passed iterators. | ||
// The iterator stops when the shortest input iterable is exhausted. | ||
// ...iterators <Array> iterators to be aggregated | ||
// Returns: <Iterator> | ||
static zip(base, ...iterators) { | ||
return new ZipIterator(toIterator(base), iterators); | ||
} | ||
|
||
// Creates an iterator that aggregates elements from each of the iterators. | ||
// | ||
// If the iterables are of uneven length, missing values are filled-in | ||
// with <undefined>. Iteration continues until the longest iterable | ||
// is exhausted. | ||
// ...iterators <Array> iterators to be aggregated | ||
// Returns: <Iterator> | ||
static zipLongest(base, ...iterators) { | ||
return new ZipIteratorLongest(toIterator(base), iterators); | ||
} | ||
|
||
// Creates an iterator that aggregates elements from each of the iterators. | ||
// | ||
// If the iterables are of uneven length, missing values are filled-in | ||
// with <defaultValue>. Iteration continues until the longest iterable | ||
// is exhausted. | ||
// defaultValue <any> value to fill-in missing values with | ||
// ...iterators <Array> iterators to be aggregated | ||
// Returns: <Iterator> | ||
static zipLongestWith(defaultValue, base, ...iterators) { | ||
return new ZipIteratorLongest(toIterator(base), iterators, defaultValue); | ||
} | ||
|
||
// Create iterator iterating over the range | ||
// Signature: start, stop[, step] | ||
// start <number> | ||
|
@@ -545,6 +601,38 @@ class ZipIterator extends Iterator { | |
} | ||
result.push(next.value); | ||
} | ||
|
||
return { done: false, value: result }; | ||
} | ||
} | ||
|
||
class ZipIteratorLongest extends Iterator { | ||
constructor(base, iterators, defaultValue) { | ||
super(base); | ||
this.done = false; | ||
this.iterators = iterators.map(toIterator); | ||
this.defaultValue = defaultValue; | ||
} | ||
|
||
next() { | ||
if (this.done) return { done: true, value: undefined }; | ||
|
||
const result = []; | ||
|
||
const next = this.base.next(); | ||
result.push(!next.done ? next.value : this.defaultValue); | ||
|
||
let allDone = next.done; | ||
for (const iterator of this.iterators) { | ||
const next = iterator.next(); | ||
result.push(!next.done ? next.value : this.defaultValue); | ||
allDone = allDone && next.done; | ||
} | ||
|
||
if (allDone) { | ||
this.done = true; | ||
return { done: true, value: undefined }; | ||
} | ||
return { done: false, value: result }; | ||
} | ||
} | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and in other places where you're mentioning the iterable protocol in combination with "exhausting", you should use the iterator contract instead since iterable only requires for an object to have a function that returns an iterator, while the iterator is an actual object that has a
next()
method and that can be "exhausted" by calling that method.