{"id":16893969,"url":"https://github.com/coolreader18/itt","last_synced_at":"2026-05-20T02:31:50.285Z","repository":{"id":104017490,"uuid":"145276494","full_name":"coolreader18/itt","owner":"coolreader18","description":"Iteration tools.","archived":false,"fork":false,"pushed_at":"2018-04-21T07:34:17.000Z","size":513,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-25T10:28:26.620Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://npm.im/itt","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coolreader18.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-19T05:39:27.000Z","updated_at":"2020-03-07T05:57:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"a4d06a3c-ca76-430f-9046-7c41f6fb3404","html_url":"https://github.com/coolreader18/itt","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coolreader18%2Fitt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coolreader18%2Fitt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coolreader18%2Fitt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coolreader18%2Fitt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coolreader18","download_url":"https://codeload.github.com/coolreader18/itt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244591502,"owners_count":20477708,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T17:17:06.617Z","updated_at":"2026-05-20T02:31:45.266Z","avatar_url":"https://github.com/coolreader18.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# itt\n\nIteration tools.\n\n```js\nfunction primes() {\n  const seen = new Set\n  return itt.irange(2)\n    .filter(p =\u003e itt(seen).every(n =\u003e p % n !== 0))\n    .tap(p =\u003e seen.add(p))\n}\n\nconsole.log(\n  itt(primes())\n  .takeWhile(x =\u003e x \u003c 1000)\n  .map(x =\u003e `${x} is prime!`)\n  .join('\\n'))\n\n/*\n2 is prime!\n3 is prime!\n5 is prime!\n7 is prime!\n11 is prime!\n...\n983 is prime!\n991 is prime!\n997 is prime!\n*/\n```\n\n# Install\n\n```sh\n$ npm i itt\n```\n\n# Use\n\n```js\nconst itt = require('itt')\n```\n\n# API\n\n**[Constructors](#constructors)** — [from(…)](#ittthing-ittfromthing) [empty()](#empty) [range(…)](#rangestart--0-end-skip--1) [irange(…)](#irangestart--0-skip--1) [replicate(…)](#replicaten-x) [forever(…)](#foreverx) [iterate(…)](#iteratex-fn)\n\u003cbr\u003e**[Object iterators](#object-iterators)** — [entries(…)](#entrieso) [keys(…)](#keyso) [values(…)](#valueso)\n\u003cbr\u003e**[Utilities](#utilities)** — [is(…)](#ittisthing) [generator(…)](#ittgeneratorg)\n\n**[Iterator Methods](#iterator-methods)**\n\u003cbr\u003e**[Slicing](#slicing)** — [.slice](#slicestart--0-end--undefined) [.drop](#dropn) [.dropWhile](#dropwhilefn) [.dropLast](#droplastn) [.take](#taken) [.takeWhile](#takewhilefn) [.takeLast](#takelastn) [.tail](#tail) [.init](#init)\n\u003cbr\u003e**[Transforming](#transforming)** — [.map](#mapfn) [.flatMap](#flatmapfn) [.filter](#filterfn) [.reject](#rejectfn) [.scan](#scana-fn) [.scan1](#scan1fn)\n\u003cbr\u003e**[Querying](#querying)** — [.first](#first) [.last](#last) [.pick](#picki) [.count](#count) [.every](#everyfn) [.some](#somefn) [.tap](#tapfn)\n\u003cbr\u003e**[Searching](#searching)** — [.find](#findfn) [.findLast](#findlastfn) [.findIndex](#findindexfn) [.findLastIndex](#findlastindexfn) [.indexOf](#indexofx) [.lastIndexOf](#lastindexofx) [.includes](#includesx)\n\u003cbr\u003e**[Manipulating](#manipulating)** — [.enumerate](#enumerate) [.intersperse](#interspersesep) [.cycle](#cycle) [.repeat](#repeatn) [.unique](#unique) [.flatten](#flatten) [.chunksOf](#chunksofn--2) [.subsequences](#subsequencesn--2) [.lookahead](#lookaheadn--1) [.transpose](#transpose)\n\u003cbr\u003e**[Combining](#combining)** — [.concat](#concatxs-) [.zip](#zipxs-) [.parallel](#parallelxs-) [.push](#pushx-) [.unshift](#unshiftx-)\n\u003cbr\u003e**[Reducing](#reducing)** — [.reduce](#reducea-fn) [.inject](#injecta-fn) [.sum](#sum) [.mean](#mean) [.product](#product) [.max](#max) [.min](#min) [.minMax](#minmax) [.join](#joinsep--) [.groupBy](#groupbyfn-unique--false) [.keyBy](#keybyfn) [.forEach](#foreachfn) [.drain](#drain)\n\u003cbr\u003e**[Conversion](#conversion)** — [.toArray](#toarray) [.toSet](#toset) [.toMap](#tomap) [.toObject](#toobjectempty--false)\n\u003cbr\u003e**[Forking](#forking)** — [.fork](#forkn--2)\n\n## Constructors\n### itt(thing), itt.from(thing)\n\nWraps an iterator. The wrapper is also iterable, and supports the methods listed [below](#iterator-methods). All functions and methods which return iterators automatically wrap them.\n\n```js\nitt(['foo', 'bar', 'baz', 'qux'])\n  .filter(x =\u003e x.startsWith('b'))\n  .map(x =\u003e x.toUpperCase())\n  .toArray()\n/* [ 'BAR', 'BAZ' ] */\n```\n\n**Note:** Many of the examples use `.toArray()` to show the elements of an iterator, but of course a feature of iterators is that they don't compute elements ahead of time (or even at all, depending on how they are iterated). For example, consider the following:\n\n```js\nconst squares = itt.irange().map(x =\u003e {\n  console.log('compute', x)\n  return x * x\n})\nfor (const y of squares.take(3)) {\n  console.log('log', y)\n}\n/* \ncompute 0\nlog 0\ncompute 1\nlog 1\ncompute 2\nlog 4\n*/\n```\n\n### empty()\n\nAn iterator which yields no values.\n\n```js\nitt.empty().toArray()\n/* [] */\n```\n\n### range([start = 0,] end, [skip = 1])\n\nAn iterator over an integer range from `start` (inclusive) to `end` (exclusive), incrementing or decrementing by `skip`.\n\n```js\nitt.range(5).map(x =\u003e x * x).toArray()\n/* [ 0, 1, 4, 9, 16 ] */\n```\n\n### irange([start = 0, [skip = 1]])\n\nAn iterator over the integers starting at `start` and incrementing or decrementing by `skip`. Best paired with `.take` or its variants.\n\n```js\nitt.irange().map(x =\u003e x * x).take(5).toArray()\n/* [ 0, 1, 4, 9, 16 ] */\n```\n\n### replicate(n, x)\n\nAn iterator which yields `x` `n` times.\n\n```js\nitt.replicate(5, 0).toArray()\n/* [ 0, 0, 0, 0, 0 ] */\n```\n\n### forever(x)\n\nAn iterator which yields `x` forever.\n\n```js\nitt.forever(0).take(5).toArray()\n/* [ 0, 0, 0, 0, 0 ] */\n```\n\n### iterate(x, fn)\n\nAn iterator which yields `x`, `fn(x)`, `fn(fn(x))`, etc.\n\n```js\nitt.iterate(1, x =\u003e x * 2).take(5).toArray()\n/* [ 1, 2, 4, 8, 16 ] */\n```\n\n## Object iterators\n\n### entries(o)\n\nAn iterator over the keys and values of an object.\n\n```js\nitt.entries({a: 1, b: 2}).toArray()\n/* [ [ 'a', 1 ], [ 'b', 2 ] ] */\n\nitt.entries({a: 1, b: 2, c: 3}).map(([k, v]) =\u003e [k, v * v]).toObject()\n/* { a: 1, b: 4, c: 9 } */\n```\n\n### keys(o)\n\nAn iterator over the keys of an object.\n\n```js\nitt.keys({a: 1, b: 2, c: 3}).map(x =\u003e x.toUpperCase()).toArray()\n/* [ 'A', 'B', 'C' ] */\n```\n\n### values(o)\n\nAn iterator over the values of an object.\n\n```js\nitt.values({a: 1, b: 2, c: 3}).map(x =\u003e x * x).toArray()\n/* [ 1, 4, 9 ] */\n```\n\n## Utilities\n\n### itt.is(thing)\n\nTrue if `thing` is iterable or an iterator.\n\n```js\nitt.is(1) // false\nitt.is('test') // true\nitt.is('test'[Symbol.iterator]()) // true\nitt.is(itt.range(5)) // true\n```\n\n### itt.generator(g)\n\nTakes a generator function and returns a generator function which returns wrapped iterators.\n\n```js\nconst fn = itt.generator(function*(...xs) {\n  yield* xs\n  xs.pop()\n  xs.reverse()\n  yield* xs\n})\nfn(1, 2, 3).map(x =\u003e x * x).toArray()\n/* [ 1, 4, 9, 4, 1 ] */\n```\n\n# Iterator Methods\n\nMethods can also be used statically by passing an iterator as the last argument. For example:\n\n```js\nitt.range(5).join() /* '0,1,2,3,4' */\nitt.join(itt.range(5)) /* '0,1,2,3,4' */\n```\n\n## Slicing\n\n### .slice([start = 0, [end = undefined]])\n\nLike `Array.prototype.slice`. Returns an iterator which yields a subsequence of the elements of this iterator, starting at the `start`th element (inclusive) and ending at the `end`th element (exclusive).\n\nIf an index is negative, that index is treated as an index from the end of the iterator. If `end` is missing, it is treated as if it were the number of elements in this iterator.\n\n```js\nitt.range(10).map(x =\u003e x * x).slice(1, 4).toArray()\n/* [ 1, 4, 9 ] */\n\nitt.range(10).map(x =\u003e x * x).slice(1, -1).toArray()\n/* [ 1, 4, 9, 16, 25, 36, 49, 64 ] */\n\nitt.range(10).map(x =\u003e x * x).slice(-3).toArray()\n/* [ 49, 64, 81 ] */\n```\n\n### .drop(n)\n\nAn iterator which yields all but the first `n` elements of this iterator.\n\n```js\nitt.range(10).drop(3).toArray()\n/* [ 3, 4, 5, 6, 7, 8, 9 ] */\n```\n\n### .dropWhile(fn)\n\nAn iterator which skips elements of this iterator until `fn(x)` returns a falsey value for an element `x`, then yields `x` and every element after it.\n\n```js\nitt([1, 2, 3, 4, 5, 4, 3, 2, 1])\n  .map(x =\u003e x * x)\n  .dropWhile(x =\u003e x \u003c 10)\n  .toArray()\n/* [ 16, 25, 16, 9, 4, 1 ] */\n```\n\n### .dropLast(n)\n\nAn iterator which yields all but the last `n` elements of this iterator.\n\n```js\nitt.range(10).dropLast(3).toArray()\n/* [ 0, 1, 2, 3, 4, 5, 6 ] */\n```\n\n**Note:** This method caches at most `n` elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .take(n)\n\nAn iterator which yields the first `n` elements of this iterator.\n\n```js\nitt.irange().take(4).toArray()\n/* [ 0, 1, 2, 3 ] */\n```\n\n### .takeWhile(fn)\n\nAn iterator which yields elements of this iterator until `fn(x)` returns a falsey value for an element `x`, then stops without yielding `x`.\n\n```js\nitt([1, 2, 3, 4, 5, 4, 3, 2, 1])\n  .map(x =\u003e x * x)\n  .takeWhile(x =\u003e x \u003c 10)\n  .toArray()\n/* [ 1, 4, 9 ] */\n```\n\n### .takeLast(n)\n\nAn iterator which yields the last `n` elements of this iterator. If this iterator yields fewer than `n` elements, it yields all available elements.\n\n```js\nitt.range(10).takeLast(3).toArray()\n/* [ 7, 8, 9 ] */\n```\n\n**Note:** This method caches at most `n` elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .tail()\n\nAn iterator which yields all but the first element of this iterator.\n\n```js\nitt.range(10).map(x =\u003e x * x).tail().toArray()\n/* [ 1, 4, 9, 16, 25, 36, 49, 64, 81 ] */\n```\n\n### .init()\n\nAn iterator which yields all but the last element of this iterator.\n\n```js\nitt.range(10).map(x =\u003e x * x).init().toArray()\n/* [ 0, 1, 4, 9, 16, 25, 36, 49, 64 ] */\n```\n\n## Transforming\n\n### .map(fn)\n\nAn iterator which yields `fn(x)` for each element `x` of this iterator.\n\n```js\nitt.range(5).map(x =\u003e x * x).toArray()\n/* [ 0, 1, 4, 9, 16 ] */\n```\n\n### .flatMap(fn)\n\nAn iterator which yields the elements of `fn(x)` for each element `x` of this iterator. Equivalent to `.map(fn).flatten()`.\n\n```js\nitt.range(5).flatMap(x =\u003e [x, x * x]).toArray()\n/* [ 0, 0, 1, 1, 2, 4, 3, 9, 4, 16 ] */\n```\n\n### .filter(fn)\n\nAn iterator which yields the elements of this iterator for which `fn` returns a truthy value.\n\n```js\nitt([1, 5, 3, 2, 5, 9, 4, 95, 1, 4, 5, 2, 8]).filter(x =\u003e x % 2).toArray()\n/* [ 1, 5, 3, 5, 9, 95, 1, 5 ] */\n```\n\n### .reject(fn)\n\nAn iterator which yields the elements of this iterator for which `fn` returns a falsey value.\n\n```js\nitt([1, 5, 3, 2, 5, 9, 4, 95, 1, 4, 5, 2, 8]).reject(x =\u003e x % 2).toArray()\n/* [ 2, 4, 4, 2, 8 ] */\n```\n\n### .scan(a, fn)\n\nAccumulates `a = fn(a, x)` for each element of this iterator, in iteration order, and yields each intermediate result. The resultant iterator always yields the same number of elements as this iterator.\n\n```js\nitt.irange().scan(0, (x, y) =\u003e x + y).take(5).toArray()\n/* [ 0, 1, 3, 6, 10 ] */\n```\n\n### .scan1(fn)\n\nLike `.scan`, but draws (and yields) the initial value of `a` from the first element of this iterator, accumulating `a = fn(a, x)` for each subsequent element.\n\n```js\nitt.irange().scan1((x, y) =\u003e x + y).take(5).toArray()\n/* [ 0, 1, 3, 6, 10 ] */\n```\n\n## Querying\n\n### .first()\n**.head() [alias]**\n\nThe first element of this iterator.\n\n```js\nitt.irange().map(x =\u003e x * x).drop(5).first()\n/* 25 */\n```\n\n### .last()\n\nThe last element of this iterator.\n\n```js\nitt.range(10).map(x =\u003e x * x).last()\n/* 81 */\n```\n\n### .pick(i)\n\nThe `i`th element of this iterator.\n\n```js\nitt.irange().map(x =\u003e x * x).pick(3)\n/* 9 */\n```\n\n### .count()\n\nThe number of elements in this iterator.\n\n```js\nitt.range(10).filter(x =\u003e x % 2).count()\n/* 5 */\n```\n\n### .every(fn)\n\nTrue if `fn(x)` returns a truthy value for every element `x` of this iterator.\n\n```js\nitt(['foo', 'bar', 'baz']).every(x =\u003e x.startsWith('b'))\n/* false */\n\nitt.range(3).map(x =\u003e x * x).every(x =\u003e x \u003c 10)\n/* true */\n```\n\n### .some(fn)\n\nTrue if `fn(x)` returns a truthy value for any element `x` of this iterator.\n\n```js\nitt(['foo', 'bar', 'baz']).some(x =\u003e x.startsWith('b'))\n/* true */\n\nitt.range(3).map(x =\u003e x * x).some(x =\u003e x \u003e 10)\n/* false */\n```\n\n### .tap(fn)\n\nAn iterator which yields each element `x` of this iterator after calling `fn(x)`. Useful for inspecting intermediate iterators with `console.log` and for running iterators through side-effectful functions.\n\n```js\nconst alnum = itt.range(0x21, 0x7f)\n  .map(String.fromCharCode)\n  .filter(s =\u003e /\\w/.test(s))\n  .tap(console.log)\nconsole.log('total: %d', alnum.count())\n/*\n0\n1\n2\n...\nx\ny\nz\ntotal: 63\n*/\n```\n\n## Searching\n\n### .find(fn)\n\nThe first element of this iterator for which `fn` returns a truthy value, or `undefined` if none exists.\n\n```js\nitt.range(10).map(x =\u003e x * x).find(x =\u003e x \u003e 10)\n/* 16 */\n\nitt.range(10).map(x =\u003e x * x).find(x =\u003e x \u003e 100)\n/* undefined */\n```\n\n### .findLast(fn)\n\nThe last element of this iterator for which `fn` returns a truthy value, or `undefined` if none exists.\n\n```js\nitt.range(10).map(x =\u003e x * x).find(x =\u003e x \u003e 10)\n/* 81 */\n\nitt.range(10).map(x =\u003e x * x).find(x =\u003e x \u003e 100)\n/* undefined */\n```\n\n### .findIndex(fn)\n\nThe 0-based index of the first element of this iterator for which `fn` returns a truthy value, or -1 if none exists.\n\n```js\nitt.range(10).map(x =\u003e x * x).findIndex(x =\u003e x \u003e 10)\n/* 4 */\n\nitt.range(10).map(x =\u003e x * x).findIndex(x =\u003e x \u003e 100)\n/* -1 */\n```\n\n### .findLastIndex(fn)\n\nThe 0-based index of the last element of this iterator for which `fn` returns a truthy value, or -1 if none exists.\n\n```js\nitt.range(10).map(x =\u003e x * x).findLastIndex(x =\u003e x \u003e 10)\n/* 9 */\n\nitt.range(10).map(x =\u003e x * x).findLastIndex(x =\u003e x \u003e 100)\n/* -1 */\n```\n\n### .indexOf(x)\n\nThe 0-based index of the first element of this iterator which is strictly equal (`===`) to `x`, or -1 if none exists.\n\n```js\nitt(['foo', 'bar', 'baz', 'bar', 'foo'])\n  .map(x =\u003e x.toUpperCase())\n  .indexOf('BAR')\n/* 1 */\n```\n\n### .lastIndexOf(x)\n\nThe 0-based index of the last element of this iterator which is strictly equal (`===`) to `x`, or -1 if none exists.\n\n```js\nitt(['foo', 'bar', 'baz', 'bar', 'foo'])\n  .map(x =\u003e x.toUpperCase())\n  .lastIndexOf('BAR')\n/* 3 */\n```\n\n### .includes(x)\n\nTrue if any element of this iterator is strictly equal (`===`) to `x`.\n\n```js\nitt.range(10).map(x =\u003e x * x).includes(16)\n/* true */\n\nitt.range(10).map(x =\u003e x * x).includes(5)\n/* false */\n```\n\n## Manipulating\n\n### .enumerate()\n\nAn iterator which yields pairs, each containing a 0-based index and element of this iterator.\n\n```js\nitt(['foo', 'bar', 'baz']).enumerate().toArray()\n/* [ [ 0, 'foo' ], [ 1, 'bar' ], [ 2, 'baz' ] ] */\n```\n\n### .intersperse(sep)\n\nAn iterator which yields `sep` between each element of this iterator.\n\n```js\nitt(['foo', 'bar', 'baz']).intersperse('or').toArray()\n/* [ 'foo', 'or', 'bar', 'or', 'baz' ] */\n```\n\n### .cycle()\n\nAn iterator which yields the elements of this iterator, in order, cycled forever.\n\n```js\nitt.range(3).cycle().take(10).toArray()\n/* [ 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 ] */\n```\n\n**Note:** This method caches all elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .repeat(n)\n\nAn iterator which yields the elements of this iterator, in order, cycled `n` times.\n\n```js\nitt.range(3).repeat(3).toArray()\n/* [ 0, 1, 2, 0, 1, 2, 0, 1, 2 ] */\n```\n\n**Note:** This method caches all elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .unique()\n\nAn iterator which yields elements of this iterator and skips elements which are `Set`-membership-equal to any that have already appeared.\n\n```js\nitt([1, 4, 7, 6, 4, 6, 5, 2, 1, 0, 9, 7]).unique().toArray()\n/* [ 1, 4, 7, 6, 5, 2, 0, 9 ] */\n```\n\n**Note:** This method caches all elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .flatten()\n\nAn iterator which yields the elements of each element of this iterator. Each element must itself be iterable.\n\n```js\nitt([[1, 2, 3], [4, 5, 6]]).flatten().toArray()\n/* [ 1, 2, 3, 4, 5, 6 ] */\n```\n\n### .chunksOf(n = 2)\n\nAn iterator which yields arrays of `n` elements from this iterator, in sequence, without duplication. If there are not an even multiple of `n` elements in total, the last array is shorter.\n\n```js\nitt.range(10).chunksOf(3).toArray()\n/* [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 9 ] ] */\n```\n\n### .subsequences(n = 2)\n\nAn iterator which yields each subsequence of `n` elements in this iterator. If there are fewer than `n` elements, yields nothing.\n\n```js\nitt.range(5).subsequences(3).toArray()\n/* [ [ 0, 1, 2 ], [ 1, 2, 3 ], [ 2, 3, 4 ] ] */\nitt.range(5).subsequences(6).toArray()\n/* [] */\n```\n\n**Note:** This method caches at most `n` elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .lookahead(n = 1)\n\nAn iterator which yields arrays, each containing an element from this iterator and `n` elements of lookahead (or `undefined` if past the end of this iterator).\n\n```js\nfor (const [here, next] of itt.range(5).lookahead()) {\n  console.log(here, next)\n}\n/*\n0 1\n1 2\n2 3\n3 4\n4 undefined\n*/\n```\n\n**Note:** This method caches at most `n` elements of this iterator. It does not pull elements from this iterator, however, until its return value is iterated.\n\n### .transpose()\n\nAn iterator which yields arrays of elements at sequential indices in each element of this iterator, whose elements must be iterable. Equivalent to `zip(...this)`.\n\n```js\nitt([[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]]).transpose().toArray()\n/* [ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ] */\n```\n\n## Combining\n\n### .concat(xs, [...])\n\nAn iterator which yields the elements of this iterator, followed by the elements of `xs`, etc.\n\n```js\nitt.range(3).concat(itt.range(5), itt.range(3)).toArray()\n/* [ 0, 1, 2, 0, 1, 2, 3, 4, 0, 1, 2 ] */\n```\n\n**Note:** This method can be called statically with any number of arguments, and yields elements in argument order.\n\n```js\nitt.concat([1, 2, 3], [4, 5, 6], [7, 8, 9]).toArray()\n/* [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] */\n```\n\n### .zip(xs, [...])\n\nAn iterator which yields arrays containing one element from this iterator and one element from each argument iterator, stopping when any iterator is done.\n\n```js\nitt.irange().zip(['a', 'b', 'c']).toArray()\n/* [ [ 0, 'a' ], [ 1, 'b' ], [ 2, 'c' ] ] */\n```\n\n**Note:** This method can be called statically with any number of arguments, and yields arrays in argument order.\n\n```js\nitt.zip([1, 2, 3], [4, 5, 6], [7, 8, 9]).toArray()\n/* [ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ] */\n```\n\n### .parallel(xs, [...])\n\nAn iterator which yields arrays containing one element from this iterator and one element from each argument iterator, stopping when all iterators are done.\n\n```js\nitt.range(5).parallel(['a', 'b', 'c']).toArray()\n/* [ [ 0, 'a' ],\n  [ 1, 'b' ],\n  [ 2, 'c' ],\n  [ 3, undefined ],\n  [ 4, undefined ] ] */\n```\n\n**Note:** This method can be called statically with any number of arguments, and yields arrays in argument order.\n\n```js\nitt.parallel([1, 2, 3], [4, 5, 6], [7, 8, 9]).toArray()\n/* [ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ] */\n```\n\n### .push(x, [...])\n\nAn iterator which yields the elements of this iterator, followed by `x`, etc.\n\n```js\nitt(['foo', 'bar']).push('baz', 'qux').toArray()\n/* [ 'foo', 'bar', 'baz', 'qux' ] */\n```\n\n### .unshift(x, [...])\n\nAn iterator which yields `x`, etc., followed by the elements of this iterator.\n\n```js\nitt(['baz', 'qux']).unshift('foo', 'bar').toArray()\n/* [ 'foo', 'bar', 'baz', 'qux' ] */\n```\n\n## Reducing\n\n### .reduce(a, fn)\n\nAccumulates `a = fn(a, x)` for each element of this iterator, in iteration order, then returns `a`.\n\n```js\nitt.range(6).reduce(0, (x, y) =\u003e x + y)\n/* 15 */\n```\n\n### .inject(a, fn)\n\nCalls `fn(a, x)` for each element of this iterator, in iteration order, then returns `a`.\n\n```js\nitt(['foo', 'bar', 'baz']).inject({}, (a, x) =\u003e a[x] = true)\n/* { foo: true, bar: true, baz: true } */\n```\n\n### .sum()\n\nThe sum of the elements of this iterator.\n\n```js\nitt.range(6).sum()\n/* 15 */\n```\n\n### .mean()\n\nThe arithmetic mean of the elements of this iterator. Returns `NaN` if this iterator has no elements.\n\n```js\nitt.range(6).mean()\n/* 2.5 */\n```\n\n### .product()\n\nThe product of the elements of this iterator.\n\n```js\nitt.range(1, 6).product()\n/* 120 */\n```\n\n### .max()\n\nThe maximum element of this iterator.\n\n```js\nitt([6, 1, 4, 9, 3, 7]).map(x =\u003e x * x).max()\n/* 81 */\n```\n\n### .min()\n\nThe minimum element of this iterator.\n\n```js\nitt([6, 1, 4, 9, 3, 7]).map(x =\u003e x * x).min()\n/* 1 */\n```\n\n### .minMax()\n\nThe minimum and maximum elements of this iterator as a pair `[min, max]`.\n\n```js\nitt([6, 1, 4, 9, 3, 7]).map(x =\u003e x * x).minMax()\n/* [1, 81] */\n```\n\n### .join(sep = ',')\n\nStringifies and concatenates all values, separated by `sep`, like `Array.prototype.join`.\n\n```js\nitt.range(5).join() /* '0,1,2,3,4' */\n```\n\n### .groupBy(fn, [unique = false])\n\nCalls `fn(x)` for each element of this iterator and returns a map from return values of `fn` to arrays of elements. If `unique` is true, use sets instead of arrays. (If `fn` is a pure function, this is equivalent to `.unique().groupBy(fn)`)\n\n```js\nitt.range(10).groupBy(x =\u003e x % 3)\n/* Map { 0 =\u003e [ 0, 3, 6, 9 ], 1 =\u003e [ 1, 4, 7 ], 2 =\u003e [ 2, 5, 8 ] } */\n\nitt([1, 4, 7, 6, 4, 6, 5, 2, 1, 0, 9, 7]).groupBy(x =\u003e x % 3, true)\n/* Map { 1 =\u003e Set { 1, 4, 7 }, 0 =\u003e Set { 6, 0, 9 }, 2 =\u003e Set { 5, 2 } } */\n```\n\n### .keyBy(fn)\n\nCalls `fn(x)` for each element of this iterator and returns a map from return values of `fn` to elements. Later elements overwrite earlier elements in the map.\n\n```js\nitt([\n  {name: 'Jane', age: 24},\n  {name: 'Alice', age: 53},\n  {name: 'Kyle', age: 33},\n]).keyBy(p =\u003e p.name.toLowerCase())\n/* Map {\n  'jane' =\u003e { name: 'Jane', age: 24 },\n  'alice' =\u003e { name: 'Alice', age: 53 },\n  'kyle' =\u003e { name: 'Kyle', age: 33 } } */\n```\n\n### .forEach(fn)\n\nCalls `fn(x)` for each element of this iterator, in iteration order. Ergonomically nicer than a `for (…) {…}` loop after a sequence of method calls or when not passing a function literal as an argument. Equivalent to `.tap(fn).drain()`.\n\n```js\nitt.irange()\n  .take(10)\n  .filter(x =\u003e x % 2)\n  .map(x =\u003e x * x)\n  .forEach(console.log)\n/*\n1\n9\n25\n49\n81\n*/\n```\n\n### .drain()\n\nConsumes all elements of this iterator and returns nothing (`undefined`). Useful for iterators with side effects. Equivalent to `.forEach(() =\u003e {})`.\n\n```js\nitt.range(5).tap(console.log).drain()\n/*\n0\n1\n2\n3\n4\n*/\n```\n\n## Conversion\n\n### .toArray()\n\nAn array of the elements in this iterator. Equivalent to `Array.from(this)`.\n\n```js\nitt.range(5).toArray()\n/* [ 0, 1, 2, 3, 4 ] */\n```\n\n### .toSet()\n\nA Set of the elements in this iterator. Equivalent to `new Set(this)`.\n\n```js\nitt.range(5).toSet()\n/* Set { 0, 1, 2, 3, 4 } */\n```\n\n### .toMap()\n\nA Map of the key-value pairs in this iterator. Equivalent to `new Map(this)`.\n\n```js\nconst m = new Map\nm.set('a', 1)\nm.set('b', 2)\nm.set('c', 3)\nitt(m).map(([k, v]) =\u003e [k + '!', v * v]).toMap()\n/* Map { 'a!' =\u003e 1, 'b!' =\u003e 4, 'c!' =\u003e 9 } */\n```\n\n### .toObject(empty = false)\n\nAn object containing the key-value pairs in this iterator. If `empty` is true, starts with `Object.create(null)` instead of `{}`.\n\n```js\nitt(['foo', 'bar', 'baz']).map(s =\u003e [s, s.toUpperCase()]).toObject()\n/* { foo: 'FOO', bar: 'BAR', baz: 'BAZ' } */\n```\n\n## Forking\n\n### .fork(n = 2)\n\nAn array of `n` iterators which all yield every element of this iterator in sequence.\n\n```js\nconst [a, b] = itt.range(5).fork()\nitt.zip(\n  a.map(x =\u003e x * x),\n  b.map(x =\u003e x * x * x)).toArray()\n/* [ [ 0, 0 ], [ 1, 1 ], [ 4, 8 ], [ 9, 27 ], [ 16, 64 ] ] */\n```\n\n**Note:** This method caches some elements of this iterator. As any derived iterator advances, new elements are cached, and once every derived iterator has advanced past an element, that element is discarded.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoolreader18%2Fitt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoolreader18%2Fitt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoolreader18%2Fitt/lists"}