{"id":18348660,"url":"https://github.com/averagehelper/node-lazy-sequence","last_synced_at":"2025-10-09T09:32:58.305Z","repository":{"id":54171411,"uuid":"343897993","full_name":"AverageHelper/node-lazy-sequence","owner":"AverageHelper","description":"An implementation of lazy arrays in Node.js","archived":false,"fork":false,"pushed_at":"2021-03-05T15:27:30.000Z","size":210,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-15T14:53:55.427Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AverageHelper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-02T20:04:33.000Z","updated_at":"2021-03-05T15:27:32.000Z","dependencies_parsed_at":"2022-08-13T08:20:11.034Z","dependency_job_id":null,"html_url":"https://github.com/AverageHelper/node-lazy-sequence","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AverageHelper%2Fnode-lazy-sequence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AverageHelper%2Fnode-lazy-sequence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AverageHelper%2Fnode-lazy-sequence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AverageHelper%2Fnode-lazy-sequence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AverageHelper","download_url":"https://codeload.github.com/AverageHelper/node-lazy-sequence/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248128613,"owners_count":21052439,"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-11-05T21:18:44.803Z","updated_at":"2025-10-09T09:32:53.285Z","avatar_url":"https://github.com/AverageHelper.png","language":"TypeScript","readme":"# Lazy Sequence\n\n\u003e An implementation of lazy arrays in Node.js.\n\n[![Tests](https://github.com/AverageHelper/node-lazy-sequence/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/AverageHelper/node-lazy-sequence/actions/workflows/build.yml)\n\nI've long been fascinated by [Swift's `LazySequence` structures](https://developer.apple.com/documentation/swift/lazysequence). The idea of simplifying sequence operations by performing them at once, rather than in several iterations, seems a simple and very reasonable optimization for some circumstances.\n\nWhy not have the same in Node? This is an experiement on how that might go.\n\n## Prerequisites\n\nThis project requires NodeJS (version 6 or later) and NPM.\n[Node](https://nodejs.org/) and [NPM](https://npmjs.org/) are really easy to install.\nTo make sure you have them available on your machine,\ntry running the following command:\n\n```sh\n$ npm -v \u0026\u0026 node -v\n6.14.11\nv10.23.0\n```\n\n## Install\n\n**BEFORE YOU INSTALL:** please read the [prerequisites](#prerequisites)\n\n```sh\n$ npm install lazy-sequence\n```\n\n## Table of contents\n\n- [Lazy Sequence](#lazy-sequence)\n  - [Prerequisites](#prerequisites)\n  - [Install](#install)\n  - [Table of contents](#table-of-contents)\n  - [Usage](#usage)\n    - [Running the tests](#running-the-tests)\n    - [Building a distribution version](#building-a-distribution-version)\n  - [Performance](#performance)\n  - [API](#api)\n    - [`lazy`](#lazy)\n    - [`LazySequence`](#lazysequence)\n    - [`toArray` and `forEach`](#toarray-and-foreach)\n    - [`map`](#map)\n    - [`filter`](#filter)\n  - [Contributing](#contributing)\n  - [Built With](#built-with)\n  - [Versioning](#versioning)\n  - [Authors](#authors)\n  - [License](#license)\n\n## Usage\n\n```TypeScript\nimport { lazy } from \"lazy-sequence\";\n\nconst foo = [\"some\", \"elements\", \"go\", \"here\"];\nconst bar = lazy(foo)\n  .map(str =\u003e str.toLocaleUpperCase())\n  .filter(str =\u003e str.length \u003e 2)\n  .map(str =\u003e str);\n\n// None of these `map` and `filter` methods have done anything yet!\n\nconst baz = bar.toArray(); // Here is where the magic happens\n\nconsole.log(baz); // [\"SOME\", \"ELEMENTS\", \"HERE\"]\n```\n\n### Running the tests\n\nStart by cloning this repo to your local machine:\n\n```sh\n$ git clone https://github.com/AverageHelper/node-lazy-sequence.git\n$ cd node-lazy-sequence\n```\n\nInstall the necessary dependencies:\n\n```sh\n$ npm install\n```\n\nTo run all tests with code coverage, run:\n\n```sh\n$ npm test\n```\n\nTo run tests on files you've changed and automatically rerun tests as changes occur, run:\n\n```sh\n$ npm run test:watch\n```\n\nTo run the style linter, run:\n\n```sh\n$ npm run lint\n```\n\n### Building a distribution version\n\n```sh\n$ npm run build\n```\n\nThis task will create a distribution version of the project\ninside a new local `dist/` folder.\n\n## Performance\n\nThe core concept is a bit complicated. Unlike plain JavaScript `Array` mutations, `map` and `filter` operations occur at once, in order, on each element of the array at the first loop. Rather than iterating over the whole sequence once for _each_ operation, `LazySequence` loops exactly _once_ over the sequence, running the registered operations in one go. This behavior saves precious compute time for more important tasks, whatever you want your program to do!\n\nA lazy sequence, as implemented here and on many computer systems, doesn't have much performance improvement over regular `Array`s until the array contains about 100,000 items. Algorithmically, the benefits are clear. Realistically, computers prefer repetitive tasks, like running lots of `map`s and then lots of `filter`s, to switching between `map` and `filter` operations quickly.\n\nI'm not sure how to improve the performance of this package much further. Pull requests are welcome!\n\n## API\n\n### `lazy`\n\nThe `lazy` function creates a new [`LazySequence`](#lazysequence) using the provided array.\n\n```TypeScript\nimport { lazy } from \"lazy-sequence\";\n\nconst foo = [\"some\", \"elements\", \"go\", \"here\"];\nconst bar = lazy(foo);\n```\n\n### `LazySequence`\n\nThis class is the primary interface for all transformations or queries we might want to perform on our array.\n\nYou can create a `LazySequence` yourself using the `lazy` function described above or by using its constructor:\n\n```TypeScript\nimport { LazySequence } from \"lazy-sequence\";\n\nconst foo = new LazySequence([\"bar\", \"baz\"]);\n```\n\nCalling `lazy` on an array is effectually identical to calling this constructor. Neither `lazy` nor `LazySequence` copies that array explicitly. We only reference it later when the data needs to be accessed.\n\n### `toArray` and `forEach`\n\nCalling the `forEach` method on a `LazySequence` right after creating the sequence (i.e., when you've applied no operations) returns a copy of the original array. `forEach` works through the operation tree and ensures that only transformed and filtered elements are returned to the caller.\n\nThe `toArray` method works by constructing a new array from the results of `forEach`.\n\n`forEach` executes any `map` or `filter` operations for each sequence element in turn before returning that element to the caller. The original array is left unaltered.\n\n### `map`\n\n```TypeScript\nconst foo: LazySequence\u003c...\u003e;\n...\nconst bar = foo\n  .map(a =\u003e transform(a));\n```\n\nThe `map` method wraps the sequence in a `LazyMapSequence` object. When `forEach` is called on this object, the returned values will have been transformed using the function passed into `map`.\n\nNo immediate computations take place until `forEach` or `toArray` is called on the sequence.\n\n### `filter`\n\n```TypeScript\nconst foo: LazySequence\u003c...\u003e;\n...\nconst bar = foo\n  .filter(a =\u003e !!a);\n```\n\nThe `filter` method wraps the sequence in a `LazyFilterSequence` object. When `forEach` is called on this object, the only returned values are those for which the function passed into `filter` returns `true`.\n\nNo immediate computations take place until `forEach` or `toArray` is called on the sequence.\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests to us.\n\n1.  Fork it!\n2.  Create your feature branch: `git checkout -b my-new-feature`\n3.  Add your changes: `git add .`\n4.  Commit your changes: `git commit -am 'Add some feature'`\n5.  Push to the branch: `git push origin my-new-feature`\n6.  Submit a pull request :sunglasses:\n\n## Built With\n\n- [Visual Studio Code](https://code.visualstudio.com/)\n- Love\n\n## Versioning\n\nWe use [SemVer](https://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/AverageHelper/node-lazy-sequence/tags).\n\n## Authors\n\n- **James Robinson** - _Initial work_ - [AverageHelper](https://github.com/AverageHelper)\n\n## License\n\n[GNU General Public License v3.0](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faveragehelper%2Fnode-lazy-sequence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faveragehelper%2Fnode-lazy-sequence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faveragehelper%2Fnode-lazy-sequence/lists"}