Cyclist is a lightweight, dependency free cyclical doubly linked list implementation in TypeScript.
Head and tail nodes automatically reference each other. This allows for simpler iteration over cyclic data structures.
The LinkedList class provides various methods for maintaining the list itself and accessing nodes (see Usage
below).
LinkedLists are iterable and can be instantiated with any iterable.
This linked list implementation is intended for small sets of data that are cyclic in nature. It provides a convenient mechanism to access values by their relationship to each other (such as musical notes or intervals in the 12 tone equal temperment system)
install with your package manager of choice and import
import {LinkedList} from 'Cyclist'
A list contains nodes that have a data property, The LinkedList class takes a generic type that will match the data property for each node.
Each node references a next and previous node via the next
and previous
properties.
New lists can be instantiated with or without data. The following approaches are extensionally equivalent.
// instantiating an empty list first
const niceList = new LinkedList()
niceList.addLast(1)
niceList.addLast(2)
// instantiating a list with data from an iterable
const equallyNiceList = new LinkedList([1, 2])
const anotherEquallyNiceList = new LinkedList(equallyNiceList)
Nodes can be added to lists at the head, tail, or any given index. New Nodes are created automatically by the insertion method with no requirement to manually instantiate a new node.
niceList.addFirst(1)
niceList.size // 1
niceList.addLast(3)
niceList.size // 2
niceList.insert(1, 2)
niceList.size // 3
Nodes can be accessed individually by Index
// maybe don't do this if the node's index will change
const niceListHead = niceList.at(0)
this method can also take a callback for side effects
const logNode = node => {
console.log(node)
return node
}
niceList.at(0, logNode) // data: 1, next: [Node], previous: [Node]
lists can also be iterated over to execute side effects (similar to Array.forEach
)
niceList.forEach(logNode) // data: 1, next: [Node], previous: [Node]
// data: 2, next: [Node], previous: [Node]
// data: 3, next: [Node], previous: [Node]
Specific nodes are removed by a given index
niceList.remove(1)
niceList.size // 2
Additionally, all nodes can be removed at once
niceList.clear()
niceList.size // 0
Note: When Nodes are removed, they are unlinked from the surrounding nodes