Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
iter-tools
Advanced tools
iter-tools
provides a comprehensive suite of utility methods for working with javascript iterables and async iterables. Iterables offer an abstraction for describing sequences of values. If you're not sure if iter-tools
is the right library for you, check out our features.
import { filter } from 'iter-tools';
const { filter } = require('iter-tools');
You are responsible for loading core-js
if your environment does not define Symbol.iterator
.
The iter-tools-es package is also available for environments with native support for es2018 syntax.
Please read our API docs!
Historical docs are markdown files on github. For 6.x docs look at tags on the history of README.md. For 7.x versions look at tags on the history of API.md.
If you're not already familiar with what iterator tools can offer you and why you may want to use them, read on.
While I try to include the most important concepts here, additional content is present also in the github wiki, including a cookbook providing author and user-submitted examples of ways to use the library to accomplish common tasks.
Iterables will never replace arrays, but they have several advantages which make them the future for high-level work in Javascript.
Defining an API in terms of iterables frees you from needing to worry about how data is stored. If you only expect iterables your code will not break when the data you expect changes from being an Array
to being a Set
or a computed representation of values stored elsewhere (or not stored at all). When only the iterable contract is used you will also be freed from other worries like a callee unexpectedly mutating a caller's data.
Iterables are lazy, which means they do work only when the results of that work are needed. Sometimes this can save you having to do any work! This also allows iterables to definite infinite sequences which are not possible to store in an array. range()
for example returns the sequence of all positive integers.
The use of small, short-lived objects with predictable shapes (like the { value, done }
object returned by iterator.next()
) is preferable in situations where responsiveness is a bigger concern than raw speed, most notably web applications (and especially inside of tight loops such as mouse event handlers). This is because generational garbage collectors are optimized for such objects, and can free their memory in imperceptably-fast minor GCs.
All javascript data types designed for the storage of data (Array, Map, and Set) are iterable, and any object or class can be made iterable by implementing a Symbol.iterator method which returns an iterator. For more reading on what is iterable and how to define iterables, see the docs for isIterable.
Iterables are usually consumed with the for..of loop syntax or the destructuring assignment syntax (e.g. const [a, b] = iterable
). They can also be consumed by iter-tools
methods.
Some iterables are also iterators, earning them the name IterableIterator
. Any iterables returned by iter-tools
methods (e.g. filter) are iterable iterators because they are implemented using generator functions. This means they can be used in one of two ways:
import { filter, notUndefined } from 'iter-tools';
// as an iterable:
for (const value of filter(notUndefined, iterable)) {
/* ... */
}
// or as an iterator:
class SparseArray extends Array {
[Symbol.iterator]() {
return filter(notUndefined, this);
}
}
iter-tools
is one of a handful of libraries that offer some common functionality like map
and filter
methods. It offers these features in addition to the common functionality:
null
and undefined
as empty iterables.Iterable
returned is an IterableIterator
.import { filter } from 'iter-tools';
const { filter } = require('iter-tools');
You are responsible for loading core-js
if your environment does not define Symbol.iterator
.
The iter-tools-es package is also available for environments with native support for es2018 syntax.
It is possible to import individual methods from the library. This will make the resulting program or application faster to initialize as it avoids the need to parse the whole library (including parts of it which may not be used). Note that this will not be nececssary for code which will be bundled prior to shipping, as modern versions of rollup and webpack will remove the unused code. Importing a single method looks like this:
const notUndefined = require('iter-tools/methods/not-undefined');
If you happen to be transpiling the code and have use of the fantastic babel-plugin-macros
, you can generate single-method imports effortlessly like so:
import { filter, map } from 'iter-tools/explode.macro';
// which transpiles to:
import filter from 'iter-tools/methods/filter';
import map from 'iter-tools/methods/map';
Methods whose names begin with __
(double underscore) are safe to use – they are part of the library's public API. They are intended for use by extenders of the library and in tight loops where performance is critical.
There are some differences in the order in which arguments are passed, but these are documented along with the method's other overloads. Other less visible differences are:
__
methods are not curried. You must pass all their arguments in a single call
__
methods (aside from __wrap
) do not treat null
and undefined
as iterables.
__
methods do not permit sync iterables to be used in place of async iterables (this could change in the future).
__
methods return singleton iterable iterators. You can only loop over the results once.
__
methods may expose implementation internals which are not part of the documented public API. Code using undocumented APIs is subject to breakage in any release, in accordance with the semver specification.
__
methods do not have type definitions.
Some major improvements are still to come. They are:
@iter-tools/regex
for evaluating regular expressions against iterables@iter-tools/unicode
for turning strings into iterables of graphemes or extended grapheme clustersSome methods in iter-tools consume an entire iterable, such as arrayFrom
, last
, or cycle
. These methods will not terminate if you pass them an infinite iterable such as range()
. Eventually we may have a better system for warning you in the circumstances when we know you've done something obviously wrong like cycle(range())
, but this does not exist yet.
iter-tools
does not aim to provide all possible operations. If a method only makes sense when its input or output is an array, iter-tools
probably does not have an implementation. groupBy
is probably the most common example of this. I may in the future create an @iter-tools/array
package for such methods if there is sufficient demand.
I give a lot of credit to the great itertools Python library. This package doesn't want to be a mere port, but rather aims to solve the same problems as Python's library.
Many thanks to Maurizio Lupo (sithmel) for doing the initial porting and development from Python's itertools, for being accepting of new contributors (and patient with us), and for eventually passing maintainership along.
FAQs
The iterable toolbox
The npm package iter-tools receives a total of 4,683 weekly downloads. As such, iter-tools popularity was classified as popular.
We found that iter-tools demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.