
Product
Rust Support Now in Beta
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
@toolbuilder/list
Advanced tools
Small, mutable, double linked, iterable list.
List
supports iteration over values and nodes. If you wish to have functions like map, filter, forEach, and such, please use an iterable or Observable library. One such possibility is Iterablefu.
npm install --save @toolbuilder/list
Import the library like this. Typescript users may also want to import Node
for explicit typing.
import { List } from '@toolbuilder/list'
Quick example:
import { List } from '@toolbuilder/list'
const list = new List(['A', 'B', 'D'])
console.log(list.length) // prints 3
list.push('E') // add 'E' to the end of the list
console.log(list.first()) // prints 'A'
const node = list.find(value => value === 'B')
list.insertAfter(node, 'C') // list is ['A', 'B', 'C', 'D', 'E'] now
console.log(list.last()) // prints 'B'
for (const value of list) {
// do something here
}
There are four ways to construct a list:
import { List } from '@toolbuilder/list'
const list1 = new List(['A', 'B', 'C']) // parameter optional
const list2 = List.from(['A', 'B', 'C']) // parameter optional
const list3 = List.of('A', 'B', 'C') // parameters optional
const list4 = list1.slice() // optional parameters will produce subset
There are three methods for iterating over the contents of a list:
// reverse a list
const list = new List(['a', 'b'])
const reversed = List.from(list.nodesReversed())
Some methods work with Node
objects to change the structure of the list. For convenience, other methods work with list values directly. For example, List.first()
returns the value of the first element, and List.firstNode()
returns the first Node
. Nodes
are required for operations such as List.insertBefore(node, value)
and List.remove(node)
.
These methods use values, not Nodes:
Iterable
API documentation follows.
The JsDoc comments use Typescript types so the Typescript compiler can generate a types file. Some key points:
Type
. So a list containing strings would be List<string>
Iterable
. So an iterable that provides strings would be Iterable<string>
.IterableIterator
. The Generator object is returned by a generator function and conforms to both the iterable protocol and the iterator protocol.The Node object is used by insertBefore and insertAfter to specify where to insert a new value. Other methods return Nodes to support using those two methods. Nodes are only valid for the List that created them.
The Node object has a value
property, which provides the value associated with that node.
Other properties and methods of the Node object are subject to change, and are not considered part of the public API.
Parameters:
const list = List.of('A', 'C')
list.insertAfter(list.firstNode(), 'B')
console.log([...list]) // prints ['A', 'B', 'C']
const node = list.firstNode()
console.log(node.value) // prints 'A'
Double-linked list.
Parameters:
iterable
Iterable<Type>? builds list using iterable (optional, default null
)Provides the number of elements in the list.
Type: number
Provides the first value in the list. Returns undefined if the list is empty.
const list = List.from(['a', 'b', 'c'])
console.log(list.first()) // prints 'a'
Returns Type first value in list
Provides the last value in the list. Returns undefined if the list is empty.
const list = List.from(['A', 'B', 'C'])
console.log(list.last()) // prints 'C'
Returns Type last value in the list
Provides the first node in the list. Returns undefined if list is empty.
const list = List.from(['a', 'b', 'c'])
const node = list.firstNode()
console.log(node.value) // prints 'a'
Returns Node<Type> first node in list
Provides the last node in the list. Returns undefined if list is empty.
const list = List.from(['A', 'B', 'C'])
const node = list.lastNode()
console.log(node.value) // prints 'C'
Returns Node<Type> last node in list
Provides the node that comes before the provided node.
Parameters:
node
Node<Type> any Node element provided by the List instanceconst list = List.from(['A', 'B', 'C'])
const node = list.lastNode()
const prevNode = list.previousNode(node)
console.log(prevNode.value) // prints 'B'
Returns Node<Type> value - the Node that comes before provided node or undefined if provided node is the first node or undefined.
Provides the node that comes after the provided node.
Parameters:
node
Node<Type> any Node element provided by the List instanceconst list = List.from(['A', 'B', 'C'])
const node = list.firstNode()
const nextNode = list.nextNode(node)
console.log(nextNode.value) // prints 'B'
Returns Node<Type> value - the Node that follows provided node or undefined if provided node is the last node or undefined.
Insert value after a node.
Parameters:
prevNode
Node<Type> node from this list to insert value behindvalue
Type value to insertconst list = new List(['A', 'B', 'D'])
const prevNode = list.find(value => value === 'B')
list.insertAfter(prevNode, 'C')
console.log([...list]) // prints ['A', 'B', 'C', 'D']
Returns Node<Type> the newly created node
Insert value before a node.
Parameters:
nextNode
Node<Type> node from this list to insert value in front ofvalue
Type value to insertconst list = new List(['A', 'C', 'D'])
const nextNode = list.find(value => value === 'C')
list.insertBefore(nextNode, 'B')
console.log([...list]) // prints ['A', 'B', 'C', 'D']
Returns Node<Type> the newly created node
Remove a node from the list.
Parameters:
node
Node<Type> the node to remove from the list. The node is no longer useable after this call,
and no longer references the associated value.const list = new List(['A', 'B', 'C', 'D'])
const node = list.find(value => value === 'C')
list.remove(node)
// at this point the variable 'node' is no longer useable, node.value will return null.
console.log([...list]) // prints ['A', 'B', 'D']
Add a value to the end of the list.
Parameters:
value
Type to be added to end of listconst list = new List(['A', 'B', 'C'])
const node = list.push('D')
console.log([...list]) // prints ['A', 'B', 'C', 'D']
console.log(node.value) // prints 'D'
Returns Node<Type> the newly created Node
Remove the last value in the list.
const list = new List(['A', 'B', 'C'])
const value = list.pop()
console.log([...list]) // prints ['A', 'B']
console.log(value) // prints 'C'
Returns Type the value of the removed node, or undefined if the list was empty
Find the first value in the list where callback(value) returns truthy.
Parameters:
callback
FindFunction<Type> called for each value in the list until returns truthythisArg
object? value to use as this
when calling callback, defaults to null (optional, default null
)const list = new List(['A', 'B', 'C', 'D'])
const node = list.find(value => value === 'C')
console.log(node.value) // prints 'C'
Returns Node<Type> the node that contains the value. The value property will provide the value. Returns undefined if there was no value where callback returned truthy.
Remove first node from list, and return the value. When combined with
push
, this enables List
to work like a FIFO queue.
const list = List.from(['A', 'B', 'C'])
const value = list.shift()
console.log(value) // prints 'A'
console.log([...list]) // prints ['B', 'C']
Returns Type the value of the first node before the call to shift
,
or undefined if the list is empty.
Push a value onto the front of the list.
Parameters:
value
Type to be added to front of listconst list = new List(['B', 'C', 'D'])
const node = list.unshift('A')
console.log([...list]) // prints ['A', 'B', 'C', 'D']
console.log(node.value) // prints 'A'
Returns Node<Type> the newly created Node
Creates a shallow copy of the list, with optional parameters to create a subset of the original list. The Nodes of the copy are different, and cannot be used with the original list. Modifying the list will not modify the parent list. However, modifying values will modify values in the parent list if they are not primitives.
Parameters:
firstNode
Node<Type>? copy starts with this node. If firstNode is undefined, the first value of the copy
is list.first(). (optional, default undefined
)lastNode
Node<Type>? last value of copy is list.previousNode(lastNode).value. If lastNode is undefined, the last
value of the copy is list.last() (optional, default undefined
)const list = List.of('A', 'B', 'C', 'D', 'E')
const cNode = list.find(c => c === 'C')
console.log([...list.slice()]) // prints ['A', 'B', 'C', 'D', 'E']
console.log([...list.slice(cNode)]) // prints ['C', 'D', 'E']
console.log([...list.slice(list.firstNode(), cNode)]) // prints ['A', 'B']
console.log([...list.slice(cNode, cNode)]) // prints []
Returns List<Type> a shallow copy of the list with the specified values
Generator function that produces each node of the list in order from first to last. The value property of each node provides the associated value.
Unexpected results may happen if the list structure is modified during iteration.
Parameters:
first
Node<Type>? iteration starts with this node. If first is undefined, the first node returned
is list.firstNode(). (optional, default undefined
)last
Node<Type>? last node returned is list.previousNode(last). If last is undefined, the last
node returned is list.lastNode() (optional, default undefined
)const list = List.from([1, 2, 3, 4])
const array = []
for (const node of list.nodes()) {
array.push(node.value)
}
console.log(array) // prints [1, 2, 3, 4]
Returns IterableIterator<Node<Type>>
Generator function that produces each node in order from last to first.
Unexpected results may happen if the list structure is modified during iteration.
Returns IterableIterator<Node<Type>>
Static constructor.
Parameters:
iterable
Iterable<U>? build list from iterable, may be null (optional, default null
)const list = List.from(['A', 'B'])
console.log([...list]) // prints ['A', 'B']
Returns List<U>
Static constructor from parameter values.
Parameters:
values
...V each value becomes an element of the list in the order providedconst list = List.of(1, 2, 'B')
console.log([...list]) // prints [1, 2, 'B']
Returns List<V>
Callback function for find. Returns truthy when value is found.
Type: Function
Parameters:
value
T candidate list valueconst list = List.from(['a', 'b'])
const findFunction = (value) => value === 'b'
const node = list.find(findFunction)
console.log(node.value) // prints 'b'
Returns any truthy if value is what you're looking for
Iterable protocol over the values in the list.
Parameters:
firstNode
Node<Type>? iteration starts with this node. If firstNode is undefined, the first value returned
is list.first().lastNode
Node<Type>? last value returned is list.previousNode(lastNode).value. If lastNode is undefined, the last
value returned is list.last()const list = List.from([1, 2, 3, 4])
const array = []
for (const value of list) {
array.push(value)
}
console.log(array) // prints [1, 2, 3, 4]
Returns IterableIterator<Type>
See the change log
Contributions are welcome. Please create a pull request.
npm install -g pnpm
pnpm install
to get the dependenciespnpm test
to run unit testspnpm run check:packfile
generates pack file to run unit tests against Node ES and CommonJS projects, as well as Electron.pnpm run check
validates the package is ready for commitThis project uses Github issues.
MIT
FAQs
Tiny, mutable, double linked, iterable list.
We found that @toolbuilder/list demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.