The ChainableIterable implements chaining for the IterableFu package. Typically, instances are created using chainable instead of creating ChainableIterable directly.
import { chainable, ChainableIterable } from 'iterablefu'
const chainableIterable = chainable([1, 2, 3])
console.log(chainableIterable instanceof ChainableIterable) // prints trueThere is a static constructor method that converts an iterable (including Generator objects) to a chainable iterable.
import { ChainableIterable } from 'iterablefu'
const a = ChainableIterable.from([1, 2, 3]).toArray()
console.log(a) // prints [1, 2, 3]There is a constructor that converts an iterable to a chainable iterable.
import { ChainableIterable } from 'iterablefu'
const a = new ChainableIterable([1, 2, 3]).toArray()
console.log(a) // prints [1, 2, 3]Static methods for creating ChainableIterables.
Concatenates a list of iterables into a single iterable.
iterables...Iterable to be concatenated
const a = ChainableIterable.concatenate([0, 1, 2], [3, 4]).toArray()
console.log(a) // prints [0, 1, 2, 3, 4]Returns ChainableIterable that provides the output of each iterable in turn
Creates a sequence from the input sequence. This function exists solely so that ChainableIterable has a static constructor method.
iterableinputIterableIterable the iterable
const fn = function * (n) {
for (i = 0; i < n; i++) {
yield i
}
}
const a = ChainableIterable.from(fn(5)).toArray()
console.log(a) // prints [0, 1, 2, 3, 4]Returns ChainableIterable that represents the same iterable that was passed in
Creates a sequence of numbers similar to the Python range. See the example.
args...integer per the example
console.log([...ChainableIterable.range()]) // prints []
console.log([...ChainableIterable.range(5)]) // prints [0, 1, 2, 3, 4]
console.log([...ChainableIterable.range(2, 5)]) // prints [2, 3, 4, 5, 6]
console.log([...ChainableIterable.range(2, 5, 3)] // prints [2, 5, 8, 11, 14]Returns ChainableIterable that represents the range
Generates a sequence of things, n times
nnumber the number of times to repeat thingthingany the repeated thing
const generator = ChainableIterable.repeat(5, 'a')
console.log([...generator]) // prints ['a', 'a', 'a', 'a', 'a']Returns ChainableIterable that will repeat thing, n times
Repeat an iterable n times.
NOTE: Generator functions are designed to create one-time-use iterables, and will not work as expected with repeatIterable. Once a generator completes, it won't restart, and therefore can't be repeated.
Instead, use an iterable object where calling [Symbol.iterator] returns a new Generator object with new state. See the examples below...
nnumber number of times to repeat iterablerepeatableIterableIterable the input iterable to repeat, see notes above and examples.
// As noted above, use functions that create iterable objects,
// not generator functions, with repeatIterable.
const repeatable = (length) => {
return {
* [Symbol.iterator] () {
for (let i = 0; i < length; i++) {
yield i
}
}
}
}
const a = ChainableIterable.repeatIterable(3, repeatable(3))
console.log([...a]) // prints [0, 1, 2, 0, 1, 2, 0, 1, 2] as expected
// NOTE: This generator function will not work as expected with repeatIterable.
const oneTime = function * (length) {
for (let i = 0; i < length; i++) {
yield i
}
}
const b = ChainableIterable.repeatIterable(3, oneTime(3))
console.log([...b]) // prints [0, 1, 2] OOPS!!!!Returns ChainableIterable that will repeat the input iterable n times
Creates a sequence of arrays the same length as the shortest iterable provided. The first array contains the first element from each of the iterables provided. The second array contains the second element from each of the iterables provided, and so on.
iterables...Iterable the iterables to be zipped
const a = [0, 1, 2]
const b = ['a', 'b', 'c', 'd', 'e', 'f'] // note that this array is longer than a
const generator = ChainableIterable.zip(a, b)
console.log([...generator]) // prints [[0, 'a'], [1, 'b'], [2, 'c']]Returns ChainableIterable for the zipped arrays
Creates a sequence of arrays the same length as the longest iterable provided. The first array contains the first element from each of the iterables provided. The second array contains the second element from each of the iterables provided, and so on. Missing elements from the shorter iterables are set to undefined.
iterables...Iterable the iterables to be zipped
const a = [0, 1, 2]
const b = ['a', 'b', 'c', 'd'] // note that this array is longer than a
const generator = ChainableIterable.zipAll(a, b)
console.log([...generator]) // prints [[0, 'a'], [1, 'b'], [2, 'c'], [undefined, 'd']]Returns ChainableIterable for the zipped arrays
Methods for transforming a sequence.
Converts a sequence of Arrays to a sequence of Objects by assigning the property names to each array element in turn. The input sequence doesn't have to provide arrays, it can provide any sequence of iterable objects.
If the arrays are too long, extra values are ignored.
If the arrays are too short, the remaining properties are assigned undefined.
propertyNamesIterable a sequence of property namesiterableIterable a sequence of arrays (or any iterable objects)
const input = [[0, 1], [2, 3, 'a'], [4]]
const a = ChainableIterable.from(input).arrayToObject(['a', 'b']).toArray()
console.log(a) // prints [{'a': 0, 'b': 1 }, {'a': 2, 'b': 3 }, {'a': 4, 'b': undefined }]Returns ChainableIterable for the sequence of Objects
Chunk every n items into an array, and output that array in the output sequence.
nnumber the number of items to group into each array.iterableIterable the sequence of items to group
const input = [0, 1, 2, 3, 4, 5, 6]
const a = ChainableIterable.from(input).chunk(2).toArray()
console.log(a) // prints [[0, 1], [2, 3], [4, 5], [6]]Returns ChainableIterable for the chunked sequence
Execute fn(previous, current) and yields the result for each pair. Would be useful for calculating time differences between timestamps.
fnFunction fn(previous, current), yielding return valueiterableIterable the input iterable
const input = [0, 1, 2, 3, 4]
const a = ChainableIterable.from(input).diff((n, m) => m - n).toArray()
console.log(a) // prints [1, 1, 1, 1]Returns ChainableIterable if input has two or more items, output sequence is one shorter than input sequence. Otherwise, no items are output.
Keeps item from input sequence when fn(item) returns truthy. Remove items from input sequence when fn(item) returns !truthy.
fnFunction fn(item) returns truthy when item should be removediterableIterable the sequence to filter
const isEvenNumber = x => x % 2 === 0
const input = [0, 1, 2, 3, 4, 5, 6]
const a = ChainableIterable.from(input).filter(isEvenNumber).toArray()
console.log(a) // prints even numbers [0, 2, 4, 6]Returns ChainableIterable for the filtered sequence
Flattens a sequence of items one level deep. It does not flatten strings, even though they are iterable.
iterableIterable the iterable sequence to flatten
const input = [[0, 1], [2, 3], [4, 5], [6]]
const a = ChainableIterable.from(input).flatten().toArray()
console.log(a) // prints [0, 1, 2, 3, 4, 5, 6]Returns ChainableIterable for the flattened sequence
Flattens a sequence by recursively returning items from each iterable in the sequence. Does not flatten strings even though they are iterable.
iterableIterable the sequence to flatten
const input = [0, [1, 2, 3], [[4, 5], [[[6, 7]], [8, 9], 10]], 11, 12]
const a = ChainableIterable.from(input).flattenRecursive().toArray()
console.log(a) // prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]Returns ChainableIterable for the flattened sequence
Generates a sequence of items by calling fn(item) for each item.
fnFunction fn(item) returns the output itemiterableIterable the sequence to map
const input = [0, 1, 2, 3]
const a = ChainableIterable.from(input).map(x => 2 * x).toArray()
console.log(a) // prints [0, 2, 4, 6]Returns ChainableIterable for the mapped sequence
Map the input sequence to the output sequence with a generator that maps one iterator to another.
This method exists solely so that ChainableIterable supports chaining for an arbitrary generator function.
generatorFunctionFunction a function that returns an iterable object, and takes an iterable as a parameter. Typically, this will be a generator function.iterableIterable the input sequence
const fn = function * (n, iterable) {
for (let x of iterable) {
yield n * x
}
}
const input = [0, 1, 2, 3, 4]
// If your generator takes additional parameters beyond iterable, you'll need
// to wrap it with another function as shown
const wrapper = (iterable) => fn(3, iterable)
const a = ChainableIterable.from(input).mapWith(wrapper).toArray()
console.log(a) // prints [0, 3, 6, 9, 12]Returns ChainableIterable for the mapped sequence
Given a sequence of Arrays, output the nth element of each array as a sequence.
indexnumber the index of the Array to outputiterableIterable the iterable to process
const input = [[0, 1], [2, 3], [4, 5]]
const a = ChainableIterable.from(input).nth(1).toArray()
console.log(a) // prints [1, 3, 5]Returns ChainableIterable for the nth elements
Given a sequence of Objects, output the specified property of each Object as a sequence.
propertynamestring the property to extract from each ObjectiterableIterable the input sequence of Objects
const input = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}, {'a': 5, 'b': 6}]
const a = ChainableIterable.from(input).pluck('a').toArray()
console.log(a) // prints [1, 3, 5]Returns ChainableIterable for the plucked items
Reject items when fn(item) returns truthy.
fnFunction fn(item) returns truthy when item should be removed from output sequenceiterableIterable input sequence
const isEvenNumber = x => x % 2 === 0
const input = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const a = ChainableIterable.from(input).reject(isEvenNumber).toArray()
console.log(a) // prints [1, 3, 5, 7, 9]Returns ChainableIterable for the non-rejected items
Create an output sequence that is the first n items of the input sequence.
nnumber the number of items to takeiterableIterable the input sequence to take items from
const input = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const a = ChainableIterable.from(input).take(5).toArray()
console.log(a) // prints [0, 1, 2, 3, 4]Returns ChainableIterable for the first n items
Output items from the input iterable until fn(item) returns !truthy.
fnFunction fn(item) returns truthy to put item in the output sequenceiterableIterable input sequence
const input = [0, 1, 2, 3, 4, 5, 6]
const a = ChainableIterable.from(input).takeWhile(x => x != 4).toArray()
console.log(a) // prints [0, 1, 2, 3]Returns ChainableIterable for the selected items
Pass the input sequence to the output sequence without change, but execute fn(item) for each
item in the sequence.
fnFunctionfn(item)is called for each item in the sequenceiterableIterable the input sequence
const input = [1, 2, 3, 4, 5]
const a = ChainableIterable.from(input).tap(console.log).toArray()
// prints [1, 2, 3, 4, 5]Returns ChainableIterable that is equivalent to the input iterable
Methods for reducing a sequence to a single value.
Executes function fn(item, index) for each item in the iterable sequence provided.
fnFunction a function(item, index), where item is the current item in the sequence, and index is the index of the current item.iterableIterable the sequence of items to call fn(item, index) with.
const fn = (item, index) => console.log(`item - ${item}, index - ${index}`)
ChainableIterable.from([1, 2, 3]).forEach(fn) // prints the following...
// item - 1, index - 0
// item - 2, index - 1
// item - 3, index - 2Returns undefined
The reduce() method executes a reducer function on each element of the input iterable, resulting in a single output value.
fnFunction fn(accumulator, item) that returns the new accumulator valueaccumulatorany the initial accumulator valueiterableIterable the sequence to execute fn over.
const add = (a, b) => a + b
const sum = ChainableIterable.from([0, 1, 2, 3, 4]).reduce(add, 0) // sum === 10Returns any the final accumulator value
Creates an Array from the items in iterable.
iterableIterable the iterable to create the array from
const a = ChainableIterable.range(5).toArray() // a is [0, 1, 2, 3, 4]Returns Array the array