{"id":13469731,"url":"https://github.com/funkia/list","last_synced_at":"2025-04-11T03:27:32.146Z","repository":{"id":16832269,"uuid":"68184811","full_name":"funkia/list","owner":"funkia","description":"🐆 An immutable list with unmatched performance and a comprehensive functional API.","archived":false,"fork":false,"pushed_at":"2024-01-15T10:31:01.000Z","size":4964,"stargazers_count":1651,"open_issues_count":22,"forks_count":51,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-01-02T19:03:56.508Z","etag":null,"topics":["data-structures","fantasy-land","functional-programming","immutable","immutable-lists","ramda","redux"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"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/funkia.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-09-14T07:41:40.000Z","updated_at":"2024-11-30T08:26:32.000Z","dependencies_parsed_at":"2024-01-02T23:42:39.208Z","dependency_job_id":"0f44520e-8b18-4470-bd5a-ef29bf20f30f","html_url":"https://github.com/funkia/list","commit_stats":{"total_commits":413,"total_committers":27,"mean_commits":"15.296296296296296","dds":0.1743341404358354,"last_synced_commit":"ba8e89e5a5a484656bb8bfe4eaf7db9aba889a7c"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkia%2Flist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkia%2Flist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkia%2Flist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funkia%2Flist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/funkia","download_url":"https://codeload.github.com/funkia/list/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248334998,"owners_count":21086487,"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":["data-structures","fantasy-land","functional-programming","immutable","immutable-lists","ramda","redux"],"created_at":"2024-07-31T15:01:53.350Z","updated_at":"2025-04-11T03:27:32.082Z","avatar_url":"https://github.com/funkia.png","language":"TypeScript","readme":"\u003ch3 align=\"center\"\u003e\n  \u003cimg align=\"center\" src=\"assets/listopard.png\" alt=\"List logo\" width=400 /\u003e\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\nA fast immutable list with a functional API.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://gitter.im/funkia/General\"\u003e\u003cimg src=\"https://img.shields.io/gitter/room/funkia/General.svg\" alt=\"Gitter\" height=\"20\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://travis-ci.org/funkia/list\"\u003e\u003cimg src=\"https://travis-ci.org/funkia/list.svg?branch=master\" alt=\"Build Status\" height=\"20\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/funkia/list\"\u003e\u003cimg src=\"https://codecov.io/gh/funkia/list/branch/master/graph/badge.svg\" alt=\"codecov\" height=\"20\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# List\n\nList is a purely functional alternative to arrays. It is an\nimplementation of a fast persistent sequence data structure. Compared\nto JavaScript's `Array` List has three major benefits.\n\n* **Safety**. List is immutable. This makes it safer and better suited\n  for functional programming. It doesn't tempt you with an imperative API and\n  accidental mutations won't be a source of bugs.\n* **Performance**. Since List doesn't allow mutations it can be\n  heavily optimized for pure operations. This makes List much faster for\n  functional programming than arrays. [See the\n  benchmarks](https://funkia.github.io/list/benchmarks/).\n* **API**: List has a large API of useful functions and offers both chainable\n  methods and curried functions to suit every taste.\n\n## Features\n\n* **Familiar functional API**. List follows the naming conventions\n  common in functional programming and has arguments ordered for\n  currying/partial application.\n* **Extensive API**. List has all the functions known from `Array`\n  and a lot of additional functions that'll save the day once you need them.\n* **Extremely fast**. List is a carefully optimized implementation of\n  the highly efficient data-structure _relaxed radix balanced trees_. We have\n  an [extensive benchmark suite](https://funkia.github.io/list/benchmarks/) to\n  ensure optimal performance. Here is an explanation [how](https://monoid.dk/post/how-can-list-be-faster-than-native-arrays/)\n* **Several API styles**. In addition to the base API List offers [additional\n  API styles](#api-styles). Import `list/methods` to get chainable methods or\n  alterntively import `list/curried` to get a version of the API where every\n  function is curried. Both variants are 100% TypeScript compatible.\n* **Does one thing well**. Instead of offering a wealth of data\n  structures List has a tight focus on being the best immutable list possible.\n  It doesn't do everything but is designed to work well with the libraries\n  you're already using.\n* **Seamless Ramda integration**. If you know Ramda you already know\n  how to use List. List was designed to integrate [seamlessly with\n  Ramda](#seamless-ramda-integration).\n* **Type safe**. List is implemented in TypeScript. It makes full use of\n  TypeScript features to provide accurate types that covers the entire library.\n* **Fully compatible with tree-shaking**. List ships with tree-shaking\n  compatible ECMAScript modules. `import * as L from \"list\"` in itself adds\n  zero bytes to your bundle when using Webpack. Using a function adds only that\n  function and the very small (\u003c1KB) core of the library. You only pay in size\n  for the functions that you actually use.\n* **Iterable**. Implements the JavaScript iterable protocol. This\n  means that lists can be use in `for..of` loops, works with destructuring, and\n  can be passed to any function expecting an iterable. [See more](#iterable).\n* **Fantasy Land support**. List\n  [implements](#fantasy-land--static-land) both the Fantasy Land and the Static\n  Land specification.\n\n| Package | Version                                                                                 | Downloads                                                                                  | Dependencies                                                                                          | Dev Deps                                                                                                              | Install size                                                                                             | GZIP size                                                                                                                                                 |\n| ------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `list`  | [![npm version](https://badge.fury.io/js/list.svg)](https://www.npmjs.com/package/list) | [![Downloads](https://img.shields.io/npm/dt/list.svg)](https://www.npmjs.com/package/list) | [![Dependency Status](https://david-dm.org/funkia/list/status.svg)](https://david-dm.org/funkia/list) | [![devDependency Status](https://david-dm.org/funkia/list/dev-status.svg)](https://david-dm.org/funkia/list?type=dev) | [![install size](https://packagephobia.now.sh/badge?p=list)](https://packagephobia.now.sh/result?p=list) | [![gzip size](http://img.badgesize.io/https://cdn.jsdelivr.net/npm/list/dist/index.js?compression=gzip)](https://cdn.jsdelivr.net/npm/list/dist/index.js) |\n\n\n## Getting started\n\nThis section explains how to get started using List. First you'll have\nto install the library.\n\n```\nnpm i list\n```\n\nThen you can import it.\n\n```js\n// As an ES module\nimport * as L from \"list\";\n// Or with require\nconst L = require(\"list\");\n```\n\nThen you can begin using List instead of arrays and enjoy immutability\nthe performance benefits.\n\nAs a replacement for array literals List offers the function `list`\nfor constructing lists. Instead of using `[...]` to construct an array\nwith the content `...` one can use `list(...)` to construct a list\nwith the same content. Here is an example.\n\n\n```js\n// An array literal\nconst myArray = [0, 1, 2, 3];\n// The List equivalent\nconst myList = L.list(0, 1, 2, 3);\n```\n\nList has all the common functions that you know from native arrays and\nother libraries.\n\n```js\nconst myList = L.list(0, 1, 2, 3, 4, 5);\nmyList.length; //=\u003e 6\nL.filter(isEven, myList); //=\u003e list(0, 2, 4)\nL.map(n =\u003e n * n, myList); //=\u003e list(0, 1, 4, 9, 16, 25)\nL.reduce((sum, n) =\u003e sum + n, 0, myList); //=\u003e 15\nL.slice(2, 5, myList); //=\u003e list(2, 3, 4)\nL.concat(myList, L.list(6, 7, 8)); //=\u003e list(0, 1, 2, 3, 4, 5, 6, 7, 8);\n```\n\nYou'll probably also end up needing to convert between arrays and\nList. You can do that with the functions `from` and `toArray`.\n\n```js\nL.toArray(L.list(\"foo\", \"bar\")); //=\u003e [\"foo\", \"bar\"];\nL.from([\"foo\", \"bar\"]); //=\u003e L.list(\"foo\", \"bar\");\n```\n\nList offers a wealth of other useful and high-performing functions.\nYou can see them all in the [API documentation](#api-documentation)\n\n## API styles\n\nList offers several API styles. By default the library exports \"plain\"\nfunctions. Additionally curried functions can be imported from `list/curried`\nand an API with chainable methods can be imported from `list/methods`. The\ndifferences are illustrated below.\n\nThe default export offers normal plain function.\n\n```ts\nimport * as L from \"list\";\n\nconst l = L.take(5, L.sortBy(p =\u003e p.name, L.filter(p =\u003e p.age \u003e 22, people)));\n```\n\nIn `list/methods` all functions are available as chainable methods.\n\n```ts\nimport * as L from \"list/methods\";\n\nconst l = people\n  .filter(p =\u003e p.age \u003e 22)\n  .sortBy(p =\u003e p.name)\n  .take(5);\n```\n\nIn `list/curried` all functions are curried. In the example below the partially\napplied functions are composed together using Ramda's\n[`pipe`](http://ramdajs.com/docs/#pipe). Alternatively one could have used\nLodash's [`flowRight`](https://lodash.com/docs/#flow).\n\n```ts\nimport * as R from \"ramda\";\nimport * as L from \"list/curried\";\n\nconst l = R.pipe(L.filter(p =\u003e p.age \u003e 22), L.sortBy(p =\u003e p.name), L.take(5))(\n  people\n);\n```\n\n## Iterable\n\nList implements the JavaScript iterable protocol. This means that\nlists can be used with array destructuring just like normal arrays.\n\n```js\nconst myList = L.list(\"first\", \"second\", \"third\", \"fourth\");\nconst [first, second] = myList;\nfirst; //=\u003e \"first\"\nsecond; //=\u003e \"second\"\n```\n\nLists can also be used in `for..of` loops.\n\n```js\nfor (const element of myList) {\n  console.log(element);\n}\n// logs: first, second, third, fourth\n```\n\nAnd they can be passed to any function that takes an iterable as its argument.\nAs an example a list can be converted into a native\n[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).\n\n```js\nconst mySet = new Set(myList);\nmySet.has(\"third\"); //=\u003e true\n```\n\nThis works because the `Set` constructor accepts any iterable as\nargument.\n\nLists also work with [spread\nsyntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax).\nFor instance, you can call a function like this.\n\n```js\nconsole.log(...list(\"hello\", \"there\", \"i'm\", \"logging\", \"elements\"));\n```\n\nThen each element of the list will be passed as an argument to `console.log`.\n\nList also suports iterating backwards over lists through the\n[`backwards`](#backwards) function.\n\n### Iterator anti-patterns\n\nThe iterable protocol allows for some very convenient patterns and\nmeans that lists can integrate nicely with JavaScript syntax. But,\nhere are two anti-patterns that you should be aware of.\n\n1.  Don't overuse `for..of` loops. Functions like [`map`](#map) and\n    [`foldl`](#foldl) are often a better choice. If you want to perform\n    a side-effect for each element in a list you should probably use\n    [`forEach`](#forEach).\n2.  Don't use the spread syntax in destructuring\n    ```js\n    const [a, b, ...cs] = myList; // Don't do this\n    ```\n    The syntax converts the rest of the iterable (in this case a list)\n    into an array by iterating through the entire iterable. This is\n    slow and it turns our list into an array. This alternative avoids\n    both problems.\n    ```js\n    const [[a, b], cs] = splitAt(2, myList); // Do this\n    ```\n    This uses the [`splitAt`](#splitAt) function which splits and\n    creates the list `cs` very efficiently in `O(log(n))` time.\n\n## Seamless Ramda integration\n\nList is designed to work seamlessly together with Ramda. Ramda offers a large\nnumber of useful functions for working with arrays. List implements the same\nfunctions on its immutable data structure. This means that Ramda users can keep\nusing the API they're familiar with. Additionally, List offers an entry point\nwhere all functions are curried.\n\nSince List implements Ramda's array API it is very easy to convert code from\nusing arrays to using immutable lists. As an example, consider the code below.\n\n```js\nimport * as R from \"ramda\";\n\nR.pipe(R.filter(n =\u003e n % 2 === 0), R.map(R.multiply(3)), R.reduce(R.add, 0))(\n  array\n);\n```\n\nThe example can be converted to code using List as follows.\n\n```js\nimport * as R from \"ramda\";\nimport * as L from \"list/curried\";\n\nR.pipe(L.filter(n =\u003e n % 2 === 0), L.map(R.multiply(3)), L.reduce(R.add, 0))(\n  list\n);\n```\n\nFor each function operating on arrays, the `R` is simply changed to an `L`.\nThis works because List exports functions that have the same names and behavior\nas Ramdas functions.\n\n### Implemented Ramda functions\n\nThe goal is to implement the entirety of Ramda's array functions for\nList. The list below keeps track of how many of Ramda functions that\nare missing and of how many that are already implemented. Currently 61\nout of 76 functions have been implemented.\n\nImplemented: `adjust`, `all`, `any`, `append`, `chain`, `concat`, `contains`,\n`drop`, `dropLast`, `dropRepeats`, `dropRepeatsWith`, `dropWhile`, `filter`,\n`find`, `findIndex`, `findLast`, `group`, `groupWith`, `head`, `flatten`,\n`indexOf`, `intersperse`, `init`, `insert`, `insertAll`, `last`, `lastIndexOf`,\n`length`, `join`, `map`, `none`, `nth`, `pair`, `partition`, `pluck`,\n`prepend`, `range`, `reduce`, `reduceRight`, `reduceWhile`, `reject`, `remove`,\n`reverse`, `repeat`, `scan`, `sequence`, `slice`, `sort`, `splitAt`,\n`splitEvery`, `splitWhen`, `take`, `takeWhile`, `tail`,\n`takeLast`,`takeLastWhile`, `traverse`, `times`, `update`, `zip`, `zipWith`.\n\nNot implemented: `aperture`, `dropLastWhile`, `endsWith`, `findLastIndex`,\n`indexBy`, `mapAccum`, `mapAccumRight`, `startsWith`, `transpose`, `unfold`,\n`uniq`, `uniqBy`, `uniqWith`, `unnest` `without`, `xprod`.\n\n### Differences compared to Ramda\n\nWhile List tries to stay as close to Ramda's API as possible there are a few\ndeviations to be aware of.\n\n* List's curried functions do not support the `R.__` placeholder. Instead of\n  `R.reduce(R.__, 0, l)` one alternative is to use an arrow function `_ =\u003e\n  L.reduce(_, 0, l)` instead.\n* [`sort`](#sort) and [`sortWith`](#sortwith) are different compared to what\n  they do in Ramda. `L.sortWith` is equivalent to `R.sort` and `L.sort` sorts a\n  list without taking a comparison function. This makes the common case of\n  sorting a list of numbers or strings easier\n\n## Fantasy Land \u0026 Static Land\n\n\u003cimg align=\"right\" width=\"82\" height=\"82\" alt=\"Fantasy Land\" src=\"https://raw.github.com/fantasyland/fantasy-land/master/logo.png\"\u003e\n\u003cimg align=\"right\" width=\"131\" height=\"82\" src=\"https://raw.githubusercontent.com/rpominov/static-land/master/logo/logo.png\" /\u003e\n\nList currently implements the following Fantasy Land and Static Land\nspecifications: Setoid, semigroup, monoid, foldable, functor, apply,\napplicative, chain, monad.\n\nThe following specifications have not been implemented yet:\nTraversable, Ord.\n\nSince methods hinder tree-shaking the Fantasy Land methods are not\nincluded by default. In order to get them you must import it likes\nthis:\n\n```js\nimport \"list/fantasy-land\";\n```\n\n## API documentation\n\nThe API is organized into three parts.\n\n1.  [Creating lists](#creating-lists) — Functions that _create_ lists.\n2.  [Updating lists](#updating-lists) — Functions that _transform_ lists.\n    That is, functions that take one or more lists as arguments and\n    returns a new list.\n3.  [Folds](#folds) — Functions that _extracts_ values based on lists.\n    They take one or more lists as arguments and returns something that\n    is not a list.\n\n### Creating lists\n\n### `list`\n\nCreates a list based on the arguments given.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst l = list(1, 2, 3, 4); // creates a list of four elements\nconst l2 = list(\"foo\"); // creates a singleton\n```\n\n### `empty`\n\nReturns an empty list.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nconst emptyList = empty(); //=\u003e list()\n```\n\n### `of`\n\nTakes a single arguments and returns a singleton list that contains it.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nof(\"foo\"); //=\u003e list(\"foo\")\n```\n\n### `pair`\n\nTakes two arguments and returns a list that contains them.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\npair(\"foo\", \"bar\"); //=\u003e list(\"foo\", \"bar\")\n```\n\n### `from`\n\nConverts an array, an array-like or an itearble into a list.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfrom([0, 1, 2, 3, 4]); //=\u003e list(0, 1, 2, 3, 4)\n```\n\n### `range`\n\nReturns a list of numbers between an inclusive lower bound and an\nexclusive upper bound.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nrange(3, 8); //=\u003e list(3, 4, 5, 6, 7)\n```\n\n### `repeat`\n\nReturns a list of a given length that contains the specified value in\nall positions.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nrepeat(1, 7); //=\u003e list(1, 1, 1, 1, 1, 1, 1)\nrepeat(\"foo\", 3); //=\u003e list(\"foo\", \"foo\", \"foo\")\n```\n\n### `times`\n\nReturns a list of given length that contains the value of the given function called with current index.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst twoFirsOdds = times(i =\u003e i * 2 + 1, 2);\nconst dots = times(() =\u003e {\n  const x = Math.random() * width;\n  const y = Math.random() * height;\n  return { x, y };\n}, 50);\n```\n\n### Updating lists\n\n### `concat`\n\nConcatenates two lists.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\nconcat(list(0, 1, 2), list(3, 4)); //=\u003e list(0, 1, 2, 3, 4)\n```\n\n### `flatten`\n\nFlattens a list of lists into a list. Note that this function does\n_not_ flatten recursively. It removes one level of nesting only.\n\n**Complexity**: `O(n * log(m))` where `n` is the length of the outer\nlist and `m` the length of the inner lists.\n\n**Example**\n\n```js\nconst nested = list(list(0, 1, 2, 3), list(4), empty(), list(5, 6));\nflatten(nested); //=\u003e list(0, 1, 2, 3, 4, 5, 6)\n```\n\n### `prepend`\n\nPrepends an element to the front of a list and returns the new list.\n\n**Complexity**: `O(log(n))`, practically constant\n\n**Example**\n\n```js\nconst newList = prepend(0, list(1, 2, 3)); //=\u003e list(0, 1, 2, 3)\n```\n\n### `append`\n\nAppends an element to the end of a list and returns the new list.\n\n**Complexity**: `O(log(n))`, practically constant\n\n**Example**\n\n```js\nconst newList = append(3, list(0, 1, 2)); //=\u003e list(0, 1, 2, 3)\n```\n\n### `intersperse`\n\nInserts a separator between each element in a list.\n\n**Example**\n\n```js\nintersperse(\"n\", list(\"ba\", \"a\", \"a\")); //=\u003e list(\"ba\", \"n\", \"a\", \"n\", \"a\")\n```\n\n### `map`\n\nApplies a function to each element in the given list and returns a new\nlist of the values that the function return.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nmap(n =\u003e n * n, list(0, 1, 2, 3, 4)); //=\u003e list(0, 1, 4, 9, 16)\n```\n\n### `pluck`\n\nExtracts the specified property from each object in the list.\n\n**Example**\n\n```js\nconst l = list(\n  { foo: 0, bar: \"a\" },\n  { foo: 1, bar: \"b\" },\n  { foo: 2, bar: \"c\" }\n);\npluck(\"foo\", l); //=\u003e list(0, 1, 2)\n```\n\n### `update`\n\nReturns a list that has the entry specified by the index replaced with\nthe given value.\n\nIf the index is out of bounds the given list is\nreturned unchanged.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\nupdate(2, \"X\", list(\"a\", \"b\", \"c\", \"d\", \"e\")); //=\u003e list(\"a\", \"b\", \"X\", \"d\", \"e\")\n```\n\n### `adjust`\n\nReturns a list that has the entry specified by the index replaced with\nthe value returned by applying the function to the value.\n\nIf the index is out of bounds the given list is\nreturned unchanged.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\nadjust(2, inc, list(0, 1, 2, 3, 4, 5)); //=\u003e list(0, 1, 3, 3, 4, 5)\n```\n\n### `slice`\n\nReturns a slice of a list. Elements are removed from the beginning and\nend. Both the indices can be negative in which case they will count\nfrom the right end of the list.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\nconst l = list(0, 1, 2, 3, 4, 5);\nslice(1, 4, l); //=\u003e list(1, 2, 3)\nslice(2, -2, l); //=\u003e list(2, 3)\n```\n\n### `take`\n\nTakes the first `n` elements from a list and returns them in a new list.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\ntake(3, list(0, 1, 2, 3, 4, 5)); //=\u003e list(0, 1, 2)\n```\n\n### `takeWhile`\n\nTakes the first elements in the list for which the predicate returns\n`true`.\n\n**Complexity**: `O(k + log(n))` where `k` is the number of elements\nsatisfying the predicate.\n\n**Example**\n\n```js\ntakeWhile(n =\u003e n \u003c 4, list(0, 1, 2, 3, 4, 5, 6)); //=\u003e list(0, 1, 2, 3)\ntakeWhile(_ =\u003e false, list(0, 1, 2, 3, 4, 5)); //=\u003e list()\n```\n\n### `takeLast`\n\nTakes the last `n` elements from a list and returns them in a new\nlist.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\ntakeLast(3, list(0, 1, 2, 3, 4, 5)); //=\u003e list(3, 4, 5)\n```\n\n### `takeLastWhile`\n\nTakes the last elements in the list for which the predicate returns\n`true`.\n\n**Complexity**: `O(k + log(n))` where `k` is the number of elements\nsatisfying the predicate.\n\n**Example**\n\n```js\ntakeLastWhile(n =\u003e n \u003e 2, list(0, 1, 2, 3, 4, 5)); //=\u003e list(3, 4, 5)\ntakeLastWhile(_ =\u003e false, list(0, 1, 2, 3, 4, 5)); //=\u003e list()\n```\n\n### `splitAt`\n\nSplits a list at the given index and return the two sides in a pair.\nThe left side will contain all elements before but not including the\nelement at the given index. The right side contains the element at the\nindex and all elements after it.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\nconst l = list(0, 1, 2, 3, 4, 5, 6, 7, 8);\nsplitAt(4, l); //=\u003e [list(0, 1, 2, 3), list(4, 5, 6, 7, 8)]\n```\n\n### `splitWhen`\n\nSplits a list at the first element in the list for which the given\npredicate returns `true`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst l = list(0, 1, 2, 3, 4, 5, 6, 7);\nsplitWhen((n) =\u003e n \u003e 3, l); //=\u003e [list(0, 1, 2, 3), list(4, 5, 6, 7)]\n```\n\n### `remove`\n\nTakes an index, a number of elements to remove and a list. Returns a\nnew list with the given amount of elements removed from the specified\nindex.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\nconst l = list(0, 1, 2, 3, 4, 5, 6, 7, 8);\nremove(4, 3, l); //=\u003e list(0, 1, 2, 3, 7, 8)\nremove(2, 5, l); //=\u003e list(0, 1, 7, 8)\n```\n\n### `drop`\n\nReturns a new list without the first `n` elements.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\ndrop(2, list(0, 1, 2, 3, 4, 5)); //=\u003e list(2, 3, 4, 5)\n```\n\n### `dropWhile`\n\nRemoves the first elements in the list for which the predicate returns\n`true`.\n\n**Complexity**: `O(k + log(n))` where `k` is the number of elements\nsatisfying the predicate.\n\n**Example**\n\n```js\ndropWhile(n =\u003e n \u003c 4, list(0, 1, 2, 3, 4, 5, 6)); //=\u003e list(4, 5, 6)\n```\n\n### `dropLast`\n\nReturns a new list without the last `n` elements.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\ndropLast(2, list(0, 1, 2, 3, 4, 5)); //=\u003e list(0, 1, 2, 3)\n```\n\n### `dropRepeats`\n\nReturns a new list without repeated elements.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\ndropRepeats(L.list(0, 0, 1, 1, 1, 2, 3, 3, 4, 4)); //=\u003e list(0, 1, 2, 3, 4)\n```\n\n### `dropRepeatsWith`\n\nReturns a new list without repeated elements by using the given\nfunction to determine when elements are equal.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\ndropRepeatsWith(\n  (n, m) =\u003e Math.floor(n) === Math.floor(m),\n  list(0, 0.4, 1.2, 1.1, 1.8, 2.2, 3.8, 3.4, 4.7, 4.2)\n); //=\u003e list(0, 1, 2, 3, 4)\n```\n\n### `tail`\n\nReturns a new list with the first element removed. If the list is\nempty the empty list is returne.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\ntail(list(0, 1, 2, 3)); //=\u003e list(1, 2, 3)\ntail(empty()); //=\u003e list()\n```\n\n### `pop`\n\nReturns a new list with the last element removed. If the list is empty\nthe empty list is returned.\n\n**Aliases**: `init`\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\npop(list(0, 1, 2, 3)); //=\u003e list(0, 1, 2)\n```\n\n### `filter`\n\nReturns a new list that only contains the elements of the original\nlist for which the predicate returns `true`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfilter(isEven, list(0, 1, 2, 3, 4, 5, 6)); //=\u003e list(0, 2, 4, 6)\n```\n\n### `reject`\n\nReturns a new list that only contains the elements of the original\nlist for which the predicate returns `false`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nreject(isEven, list(0, 1, 2, 3, 4, 5, 6)); //=\u003e list(1, 3, 5)\n```\n\n### `reverse`\n\nReverses a list.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nreverse(list(0, 1, 2, 3, 4, 5)); //=\u003e list(5, 4, 3, 2, 1, 0)\n```\n\n### `ap`\n\nApplies a list of functions to a list of values.\n\n**Example**\n\n```js\nap(list((n: number) =\u003e n + 2, n =\u003e 2 * n, n =\u003e n * n), list(1, 2, 3)); //=\u003e list(3, 4, 5, 2, 4, 6, 1, 4, 9)\n```\n\n### `chain`\n\nMaps a function over a list and concatenates all the resulting lists\ntogether.\n\n**Aliases**: `flatMap`\n\n**Example**\n\n```js\nchain(n =\u003e list(n, 2 * n, n * n), list(1, 2, 3)); //=\u003e list(1, 2, 1, 2, 4, 4, 3, 6, 9)\n```\n\n### `partition`\n\nSplits the list into two lists. One list that contains all the values\nfor which the predicate returns `true` and one containing the values for\nwhich it returns `false`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\npartition(isEven, list(0, 1, 2, 3, 4, 5)); //=\u003e list(list(0, 2, 4), list(1, 3, 5))\n```\n\n### `insert`\n\nInserts the given element at the given index in the list.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\ninsert(2, \"c\", list(\"a\", \"b\", \"d\", \"e\")); //=\u003e list(\"a\", \"b\", \"c\", \"d\", \"e\")\n```\n\n### `insertAll`\n\nInserts the given list of elements at the given index in the list.\n\n**Complexity**: `O(log(n))`\n\n**Example**\n\n```js\ninsertAll(2, list(\"c\", \"d\"), list(\"a\", \"b\", \"e\", \"f\")); //=\u003e list(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\")\n```\n\n### `zipWith`\n\nThis is like mapping over two lists at the same time. The two lists are\niterated over in parallel and each pair of elements is passed to the function.\nThe returned values are assembled into a new list.\n\nThe shortest list determine the size of the result.\n\n**Complexity**: `O(log(n))` where `n` is the length of the smallest list.\n\n**Example**\n\n```js\nconst names = list(\"Turing\", \"Curry\");\nconst years = list(1912, 1900);\nzipWith((name, year) =\u003e ({ name, year }), names, years);\n//=\u003e list({ name: \"Turing\", year: 1912 }, { name: \"Curry\", year: 1900 });\n```\n\n### `zip`\n\nIterate over two lists in parallel and collect the pairs.\n\n**Complexity**: `O(log(n))` where `n` is the length of the smallest list.\n\n**Example**\n\n```js\nconst names = list(\"a\", \"b\", \"c\", \"d\", \"e\");\nconst years = list(0, 1, 2, 3, 4, 5, 6);\n//=\u003e list([\"a\", 0], [\"b\", 1], [\"c\", 2], [\"d\", 3], [\"e\", 4]);\n```\n\n### `sort`\n\nSorts the given list. The list should contain values that can be compared using\nthe `\u003c` operator or values that implement the Fantasy Land\n[Ord](https://github.com/fantasyland/fantasy-land#ord) specification.\n\nPerforms a stable sort.\n\n**Complexity**: `O(n * log(n))`\n\n**Example**\n\n```js\nsort(list(5, 3, 1, 8, 2)); //=\u003e list(1, 2, 3, 5, 8)\nsort(list(\"e\", \"a\", \"c\", \"b\", \"d\"); //=\u003e list(\"a\", \"b\", \"c\", \"d\", \"e\")\n```\n\n### `sortBy`\n\nSort the given list by passing each value through the function and comparing\nthe resulting value. The function should either return values comparable using\n`\u003c` or values that implement the Fantasy Land\n[Ord](https://github.com/fantasyland/fantasy-land#ord) specification.\n\nPerforms a stable sort.\n\n**Complexity**: `O(n * log(n))`\n\n**Example**\n\n```js\nsortBy(\n  o =\u003e o.n,\n  list({ n: 4, m: \"foo\" }, { n: 3, m: \"bar\" }, { n: 1, m: \"baz\" })\n);\n//=\u003e list({ n: 1, m: \"baz\" }, { n: 3, m: \"bar\" }, { n: 4, m: \"foo\" })\n\nsortBy(s =\u003e s.length, list(\"foo\", \"bar\", \"ba\", \"aa\", \"list\", \"z\"));\n//=\u003e list(\"z\", \"ba\", \"aa\", \"foo\", \"bar\", \"list\")\n```\n\n### `sortWith`\n\nSort the given list by comparing values using the given function. The function\nreceieves two values and should return `-1` if the first value is stricty\nlarger than the second, `0` is they are equal and `1` if the first values is\nstrictly smaller than the second.\n\nNote that the comparison function is equivalent to the one required by\n[`Array.prototype.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).\n\nPerforms a stable sort.\n\n**Complexity**: `O(n * log(n))`\n\n**Example**\n\n```js\nsortWith((a, b) =\u003e {\n  if (a === b) {\n    return 0;\n  } else if (a \u003c b) {\n    return -1;\n  } else {\n    return 1;\n  }\n}, list(5, 3, 1, 8, 2)); //=\u003e list(1, 2, 3, 5, 8)\n```\n\n### `group`\n\nReturns a list of lists where each sublist's elements\nare all equal.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\ngroup(list(0, 0, 1, 2, 2, 2, 3, 3)); //=\u003e list(list(0, 0), list(1), list(2, 2, 2), list(3, 3))\n```\n\n### `groupWith`\n\nReturns a list of lists where each sublist's elements are pairwise\nequal based on the given comparison function.\n\nNote that only adjacent elements are compared for equality. If all\nequal elements should be grouped together the list should be sorted\nbefore grouping.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst floorEqual = (a, b) =\u003e Math.round(a) === Math.round(b);\ngroupWith(floorEqual, list(1.1, 1.3, 1.8, 2, 2.2, 3.3, 3.4));\n//=\u003e list(list(1.1, 1.3), list(1.8, 2, 2.2), list(3.3, 3.4))\n\nconst sameLength = (a, b) =\u003e a.length === b.length;\ngroupWith(sameLength, list(\"foo\", \"bar\", \"ab\", \"bc\", \"baz\"));\n//=\u003e list(list(\"foo\", \"bar\"), list(\"ab\", \"bc\"), list(\"baz))\n```\n\n### Folds\n\n### `isList`\n\nReturns `true` if the given argument is a list.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nisList([0, 1, 2]); //=\u003e false\nisList(\"string\"); //=\u003e false\nisList({ foo: 0, bar: 1 }); //=\u003e false\nisList(list(0, 1, 2)); //=\u003e true\n```\n\n### `isEmpty`\n\nReturns `true` if the list is empty.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nisEmpty(empty()); //=\u003e true\nisEmpty(list()); //=\u003e true\nisEmpty(list(0, 1, 2)); //=\u003e false\n```\n\n### `equals`\n\nReturns true if the two lists are equivalent.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nequals(list(0, 1, 2, 3), list(0, 1, 2, 3)); //=\u003e true\nequals(list(\"a\", \"b\", \"c\"), list(\"a\", \"z\", \"c\")); //=\u003e false\n```\n\n### `equalsWith`\n\nReturns `true` if the two lists are equivalent when comparing each\npair of elements with the given comparison function.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nequalsWith(\n  (n, m) =\u003e n.length === m.length,\n  list(\"foo\", \"hello\", \"one\"),\n  list(\"bar\", \"world\", \"two\")\n); //=\u003e true\n```\n\n### `toArray`\n\nConverts a list into an array.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\ntoArray(list(0, 1, 2, 3, 4)); //=\u003e [0, 1, 2, 3, 4]\n```\n\n### `backwards`\n\nReturns an iterable that iterates backwards over the given list.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nconst l = list(0, 1, 2, 3, 4)\nfor (const n of backwards(l)) {\n  if (l \u003c 2) {\n    break;\n  }\n  console.log(l);\n}\n// =\u003e logs 4, 3, and then 2\n```\n\n### `nth`\n\nGets the `n`th element of the list. If `n` is out of bounds\n`undefined` is returned.\n\n**Complexity**: `O(log(n))`, practically constant\n\n**Example**\n\n```js\nconst l = list(0, 1, 2, 3, 4);\nnth(2, l); //=\u003e 2\n```\n\n### `length`\n\nReturns the length of a list. I.e. the number of elements that it\ncontains.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nlength(list(0, 1, 2, 3)); //=\u003e 4\n```\n\n### `first`\n\nReturns the first element of the list. If the list is empty the\nfunction returns `undefined`.\n\n**Aliases**: `head`\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nfirst(list(0, 1, 2, 3)); //=\u003e 0\nfirst(list()); //=\u003e undefined\n```\n\n### `last`\n\nReturns the last element of the list. If the list is empty the\nfunction returns `undefined`.\n\n**Complexity**: `O(1)`\n\n**Example**\n\n```js\nlast(list(0, 1, 2, 3)); //=\u003e 3\nlast(list()); //=\u003e undefined\n```\n\n### `foldl`\n\nFolds a function over a list. Left-associative.\n\n**Aliases**: `reduce`\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfoldl((n, m) =\u003e n - m, 1, list(2, 3, 4, 5));\n1 - 2 - 3 - 4 - 5; //=\u003e -13\n```\n\n### `foldr`\n\nFolds a function over a list. Right-associative.\n\n**Aliases**: `reduceRight`\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfoldr((n, m) =\u003e n - m, 5, list(1, 2, 3, 4));\n1 - (2 - (3 - (4 - 5))); //=\u003e 3\n```\n\n### `foldlWhile`\n\nSimilar to `foldl`. But, for each element it calls the predicate function\n_before_ the folding function and stops folding if it returns `false`.\n\n**Aliases**: `reduceWhile`\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst isOdd = (_acc:, x) =\u003e x % 2 === 1;\n\nconst xs = L.list(1, 3, 5, 60, 777, 800);\nfoldlWhile(isOdd, (n, m) =\u003e n + m, 0, xs) //=\u003e 9\n\nconst ys = L.list(2, 4, 6);\nfoldlWhile(isOdd, (n, m) =\u003e n + m, 111, ys) //=\u003e 111\n```\n\n### `scan`\n\nFolds a function over a list from left to right while collecting all the\nintermediate steps in a resulting list.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst l = list(1, 3, 5, 4, 2);\nL.scan((n, m) =\u003e n + m, 0, l); //=\u003e list(0, 1, 4, 9, 13, 15));\nL.scan((s, m) =\u003e s + m.toString(), \"\", l); //=\u003e list(\"\", \"1\", \"13\", \"135\", \"1354\", \"13542\")\n```\n\n### `traverse`\n\nMap each element of list to an applicative, evaluate these\napplicatives from left to right, and collect the results.\n\nThis works with Fantasy Land\n[applicatives](https://github.com/fantasyland/fantasy-land#applicative).\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst safeDiv = n =\u003e d =\u003e d === 0 ? nothing : just(n / d)\n\nL.traverse(Maybe, safeDiv(10), list(2, 4, 5)); //=\u003e just(list(5, 2.5, 2))\nL.traverse(Maybe, safeDiv(10), list(2, 0, 5)); //=\u003e nothing\n```\n\n### `sequence`\n\nEvaluate each applicative in the list from left to right, and\ncollect the results.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nL.sequence(Maybe, list(just(1), just(2), just(3))); //=\u003e just(list(1, 2, 3))\nL.sequence(Maybe, list(just(1), just(2), nothing())); //=\u003e nothing\n```\n\n### `forEach`\n\nInvokes a given callback for each element in the list from left to\nright. Returns `undefined`.\n\nThis function is very similar to `map`. It should be used instead of\n`map` when the mapping function has side-effects. Whereas `map`\nconstructs a new list `forEach` merely returns `undefined`. This makes\n`forEach` faster when the new list is unneeded.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst l = list(0, 1, 2);\nforEach(element =\u003e console.log(element));\n//=\u003e 0\n//=\u003e 1\n//=\u003e 2\n```\n\n### `every`\n\nReturns `true` if and only if the predicate function returns `true`\nfor all elements in the given list.\n\n**Aliases**: `all`\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst isEven = n =\u003e n % 2 === 0;\nevery(isEven, empty()); //=\u003e true\nevery(isEven, list(2, 4, 6, 8)); //=\u003e true\nevery(isEven, list(2, 3, 4, 6, 7, 8)); //=\u003e false\nevery(isEven, list(1, 3, 5, 7)); //=\u003e false\n```\n\n### `some`\n\nReturns `true` if and only if there exists an element in the list for\nwhich the predicate returns `true`.\n\n**Aliases**: `any`\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst isEven = n =\u003e n % 2 === 0;\nsome(isEven, empty()); //=\u003e false\nsome(isEven, list(2, 4, 6, 8)); //=\u003e true\nsome(isEven, list(2, 3, 4, 6, 7, 8)); //=\u003e true\nsome(isEven, list(1, 3, 5, 7)); //=\u003e false\n```\n\n### `indexOf`\n\nReturns the index of the _first_ element in the list that is equal to\nthe given element. If no such element is found `-1` is returned.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst l = list(12, 4, 2, 89, 6, 18, 7);\nindexOf(12, l); //=\u003e 0\nindexOf(89, l); //=\u003e 3\nindexOf(10, l); //=\u003e -1\n```\n\n### `lastIndexOf`\n\nReturns the index of the _last_ element in the list that is equal to\nthe given element. If no such element is found `-1` is returned.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst l = L.list(12, 4, 2, 18, 89, 2, 18, 7);\nL.lastIndexOf(18, l); //=\u003e 6\nL.lastIndexOf(2, l); //=\u003e 5\nL.lastIndexOf(12, l); //=\u003e 0\n```\n\n### `find`\n\nReturns the _first_ element for which the predicate returns `true`. If\nno such element is found the function returns `undefined`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfind(isEven, list(1, 3, 5, 6, 7, 9, 10)); //=\u003e 6\nfind(isEven, list(1, 3, 5, 7, 9)); //=\u003e undefined\n```\n\n### `findLast`\n\nReturns the _last_ element for which the predicate returns `true`. If\nno such element is found the function returns `undefined`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfindLast(isEven, list(1, 3, 5, 6, 7, 8, 9)); //=\u003e 8\nfindLast(isEven, list(1, 3, 5, 7, 9)); //=\u003e undefined\n```\n\n### `findIndex`\n\nReturns the index of the first element for which the predicate returns\n`true`. If no such element is found the function returns `-1`.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nfindIndex(isEven, list(1, 3, 5, 6, 7, 9, 10)); //=\u003e 3\nfindIndex(isEven, list(1, 3, 5, 7, 9)); //=\u003e -1\n```\n\n### `none`\n\nReturns `true` if and only if the predicate function returns `false`\nfor all elements in the given list.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nconst isEven = n =\u003e n % 2 === 0;\nnone(isEven, empty()); //=\u003e true\nnone(isEven, list(2, 4, 6, 8)); //=\u003e false\nnone(isEven, list(2, 3, 4, 6, 7, 8)); //=\u003e false\nnone(isEven, list(1, 3, 5, 7)); //=\u003e true\n```\n\n### `includes`\n\nReturns `true` if the list contains the specified element. Otherwise\nit returns `false`.\n\n**Aliases**: `contains`\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\nincludes(3, list(0, 1, 2, 3, 4, 5)); //=\u003e true\nincludes(3, list(0, 1, 2, 4, 5)); //=\u003e false\n```\n\n### `join`\n\nConcats the strings in a list separated by a specified separator.\n\n**Complexity**: `O(n)`\n\n**Example**\n\n```js\njoin(\", \", list(\"one\", \"two\", \"three\")); //=\u003e \"one, two, three\"\n```\n\n## Benchmarks\n\nThe benchmarks are located in the [`bench` directory](/test/bench).\n","funding_links":[],"categories":["TypeScript","Used by","redux","Libraries"],"sub_categories":["Open source projects (\u003e1k⭐)","Data Structures"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunkia%2Flist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunkia%2Flist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunkia%2Flist/lists"}