https://github.com/psenger/linked-list
Just Linked List Example
https://github.com/psenger/linked-list
Last synced: 10 months ago
JSON representation
Just Linked List Example
- Host: GitHub
- URL: https://github.com/psenger/linked-list
- Owner: psenger
- License: mit
- Created: 2021-07-10T01:15:24.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-03-06T05:49:29.000Z (almost 3 years ago)
- Last Synced: 2025-03-18T05:43:54.047Z (10 months ago)
- Language: JavaScript
- Size: 6.02 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Linked List
_ES6 Linked List for NodeJS_
> A Linked List, is a collection of elements whose order / sequence is not determined by physical
> placement in memory, but rather by each element which points to either the next or previous
> element.
[](http://standardjs.com)
## Table of contents
- [Linked List](#linked-list)
* [Installation Instructions](#installation-instructions)
* [API](#api)
+ [LinkedList](#linkedlist)
- [Parameters](#parameters)
- [clear](#clear)
- [length](#length)
- [setHead](#sethead)
* [Parameters](#parameters-1)
- [getHead](#gethead)
- [setTail](#settail)
* [Parameters](#parameters-2)
- [getTail](#gettail)
- [prepend](#prepend)
* [Parameters](#parameters-3)
* [Examples](#examples)
- [prependAll](#prependall)
* [Parameters](#parameters-4)
- [append](#append)
* [Parameters](#parameters-5)
* [Examples](#examples-1)
- [appendAll](#appendall)
* [Parameters](#parameters-6)
* [Examples](#examples-2)
- [forward](#forward)
* [Examples](#examples-3)
- [reverse](#reverse)
* [Examples](#examples-4)
- [find](#find)
* [Parameters](#parameters-7)
* [Examples](#examples-5)
+ [LinkedList~LinkedListPredicate](#linkedlistlinkedlistpredicate)
- [Parameters](#parameters-8)
+ [LinkedList~SurroundingNodes](#linkedlistsurroundingnodes)
- [Properties](#properties)
+ [Node~NodeOption](#nodenodeoption)
- [Properties](#properties-1)
+ [Node](#node)
- [Parameters](#parameters-9)
- [getData](#getdata)
- [setData](#setdata)
* [Parameters](#parameters-10)
- [getNext](#getnext)
- [setNext](#setnext)
* [Parameters](#parameters-11)
- [getPrev](#getprev)
- [setPrev](#setprev)
* [Parameters](#parameters-12)
* [Example Usage](#example-usage)
* [Deployment Steps](#deployment-steps)
* [License](#license)
## Installation Instructions
```bash
npm install @psenger/linked-list --save
```
or
```bash
yarn add @psenger/linked-list
```
## API
### LinkedList
Linked List - Constructed with either a Data Object ( which will be wrapped with a Node ) or a
Node with data in it already. Alternatively, you can construct the Linked List with no
parameters.
#### Parameters
* `data` **([Node][1] | [Object][2] | [undefined][3] | null)** Node, an Object as the data, undefined or null. (optional, default `null`)
#### clear
Clear all out the values. Resetting the Linked List.
#### length
Determine the length of the linked List. The Linked List can be altered by means outside
the control of the LinkedList Object, thereby bypassing the any functions on this object.
Therefore, the length is calculated by iterating over every value in the list. Which can be
expensive to execute if the list is large.
Returns **[number][4]** the length
#### setHead
Set the head, to either a new value, which will be encapsulated as a new Node, or by passing a
Node. Either way, the Node's next and previous values will be modified and the value or
node that is passed becomes the new head. Consequently, passing either null or undefined,
will result in clearing the entire linked list.
##### Parameters
* `newHead` **([Object][2] | [Node][1] | null | [undefined][3])** the new head, supporting either a Node, or data.
#### getHead
Get the Head of this Linked List.
Returns **(null | [Node][1])** The head, or null.
#### setTail
Set the tail, to either a new value, which will be encapsulated as a new Node, or a pass a
Node. Either way, the Node's next and previous values will be modified and the value or
node that is passed becomes the new tail. Consequently, passing either null or undefined,
will result in clearing the entire linked list.
##### Parameters
* `newTail` **([Object][2] | [Node][1] | null | [undefined][3])** the new tail, supporting either a Node, or data.
#### getTail
get the Tail of this Linked List
Returns **(null | [Node][1])** The tail, or null.
#### prepend
Prepend a new Node or Data to the head. Warning, passing null will clear the Linked List.
##### Parameters
* `data` **([Object][2] | [Node][1] | null | [undefined][3])** passing either a Node or data, null will reset
the Linked List.
##### Examples
```javascript
const ll = new LinkedList();
const nn = new Node();
nn.setData('C')
ll.prepend('A').prepend(new Node({data:'B'})).prepend(nn)
for ( let node of ll.forward ) {
console.log(node.getData());
}
console.log( 'length =', ll.getSize() );
ll.append( null )
console.log( 'length =', ll.getSize() );
> C
> B
> A
> length = 3
> length = 0
```
Returns **[LinkedList][5]** A reference to this object allowing chaining.
#### prependAll
Prepend all the values from left to right of the iterator passed in.
##### Parameters
* `values` **Iterable** Iterable values to prepend to the tail, can be either data or a Node
Returns **[LinkedList][5]** A reference to this object allowing chaining.
#### append
Append a new Node or Data to the tail. Warning, passing null will clear the Linked List.
##### Parameters
* `data` **([Object][2] | [Node][1] | null | [undefined][3])** passing either a Node or data, null will reset the Linked List.
##### Examples
```javascript
const ll = new LinkedList();
const nn = new Node();
nn.setData('C')
ll.append('A').append(new Node({data:'B'})).append(nn)
for ( let node of ll.forward ) {
console.log(node.getData());
}
console.log( 'length =', ll.getSize() );
ll.append( null )
console.log( 'length =', ll.getSize() );
> A
> B
> C
> length = 3
> length = 0
```
Returns **[LinkedList][5]** A reference to this object allowing chaining.
#### appendAll
Append all the values from left to right of the iterator passed in.
##### Parameters
* `values` **Iterable** Iterable values to append to the beginning, can be either data or a Node
##### Examples
```javascript
const ll = new LinkedList();
const nn = new Node();
nn.setData('C')
ll
.appendAll([
'A',
new Node({data: 'B'})
])
.appendAll([
nn
])
for (let node of ll.forward) {
console.log(' > ', node.getData());
}
> A
> B
> C
```
Returns **[LinkedList][5]** A reference to this object allowing chaining.
#### forward
A Forward iterator through the Linked List
##### Examples
```javascript
let ll = new LinkedList();
ll.appendAll(['A','B','E','F'])
for ( let node of ll.reverse ) {
console.log(node.getData());
}
> F
> E
> B
> A
ll.clear();
ll.appendAll([1,2,3,4])
const y = Array.from( ll.forward, node => node.getData() ).filter( v => v % 2 === 0 )
console.log(y);
> [ 2, 4 ]
```
#### reverse
A Reverse iterator through the Linked List
##### Examples
```javascript
const ll = new LinkedList();
ll.appendAll(['A','B','E','F'])
for ( let node of ll.reverse ) {
console.log(node.getData());
}
> F
> E
> B
> A
ll.clear();
ll.appendAll([1,2,3,4])
const y = Array.from( ll.reverse, node => node.getData() ).filter( v => v % 2 === 0 )
console.log(y);
> [ 4, 2 ]
```
#### find
Find provides a call back that can be used to select nodes from the Linked List.
##### Parameters
* `predicate` **[LinkedList~LinkedListPredicate][6]**
* `options` **[Object][2]** (optional, default `{iterator:this.forward,once:true}`)
* `options.iterator` **Iterator** The iterator to use, defaults to forward. (optional, default `this.forward`)
* `options.once` **[Boolean][7]** Indicates if the iteration is to halt if found once. (optional, default `true`)
##### Examples
```javascript
const ll = new LinkedList();
const evenCallBack = (cn,pn,nn,iteration,hitCount,linkedList) => cn.getData() % 2 === 0;
ll.appendAll([1,2,3,4])
const results = ll.find(evenCallBack,{once:false}).map(({currentNode})=>currentNode?.getData());
console.log('Even values=', results);
// Even values= [ 2, 4 ]
ll.clear();
const findIt = (value) => (cn,pn,nn,iteration,hitCount,linkedList) => cn.getData() === value;
ll.appendAll(['A','B', 'C','D']) // insert Z between B and C
const [ { previousNode, currentNode, nextNode } ] = ll.find(findIt('B'),{once:true});
console.log('previousNode', previousNode?.getData());
// previousNode A
console.log('currentNode', currentNode?.getData());
// currentNode B
console.log('nextNode', nextNode?.getData());
// nextNode C
const newNode = new Node();
newNode.setData('Z');
currentNode?.setNext( newNode );
nextNode?.setPrev( newNode );
newNode.setPrev( currentNode );
newNode.setNext( nextNode );
console.log('---- Forward ----');
for ( let node of ll.forward ) {
console.log(node.getData());
}
// ---- Forward ----
// A
// B
// Z
// C
// D
console.log('---- Reverse ----');
for ( let node of ll.reverse ) {
console.log(node.getData());
}
// ---- Reverse ----
// D
// C
// Z
// B
// A
```
Returns **[Array][8]<[LinkedList~SurroundingNodes][9]>** matching nodes
### LinkedList~LinkedListPredicate
Callback, used by find to predicate nodes, in the Linked List.
Type: [Function][10]
#### Parameters
* `currentNode` **(null | [Node][1])** The current Node
* `previousNode` **(null | [Node][1])** The previous Node
* `nextNode` **(null | [Node][1])** The next Node
* `iteration` **[number][4]** Iteration number
* `hitCount` **[number][4]** A running count of all the evaluated predicates that matched true.
* `scope` **[LinkedList][5]** The LinkedList Object.
Returns **[boolean][7]** true indicates a match and will collect matching node(s)
### LinkedList~SurroundingNodes
Type: [Object][2]
#### Properties
* `previousNode` **(null | [Node][1])** previous node
* `currentNode` **(null | [Node][1])** current node
* `nextNode` **(null | [Node][1])** next node
### Node~NodeOption
A Node constructor option object
Type: [Object][2]
#### Properties
* `data` **([Object][2] | null)** Any kind of data you want to store.
* `next` **([Node][1] | null)** Next node
* `prev` **([Node][1] | null)** Previous node
### Node
Node, the internal class used within the linked list to assist in linking elements.
#### Parameters
* `props` **[Node~NodeOption][11]** the Options to pass to the
constructor (optional, default `{data:null,next:null,prev:null}`)
* `props.data` **([Object][2] | null)** the data to store (optional, default `null`)
* `props.next` **([Node][1] | null)** the next node, or null (optional, default `null`)
* `props.prev` **([Node][1] | null)** the previous node, or null (optional, default `null`)
#### getData
Get the data from this node, which can be what ever you want.
Returns **(any | null)** the data stored here.
#### setData
Set the data in this node.
##### Parameters
* `data` **(any | null)** the data to store.
#### getNext
Get the next node, null indicates that it is the end.
Returns **([Node][1] | null)** the next node.
#### setNext
Set the next node, null indicates the end.
##### Parameters
* `node` **([Node][1] | null)** the next node.
#### getPrev
Get the previous node. The value null indicate the end has been reached.
Returns **([Node][1] | null)** the previous node.
#### setPrev
Set the previous node, null indicates the end.
##### Parameters
* `node` **([Node][1] | null)** the previous node.
[1]: #node
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[5]: #linkedlist
[6]: #linkedlistlinkedlistpredicate
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
[9]: #linkedlistsurroundingnodes
[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
[11]: #nodenodeoption
## Example Usage
```javascript
const LinkedList = require('./LinkedList');
const ll = new LinkedList();
ll.append('A').append('B').append('C')
for (let node of ll.forward) {
console.log(node.getData());
}
console.log('head=',ll.getHead().getData());
console.log('tail=',ll.getTail().getData());
```
## Deployment Steps
These are notes for deploying to NPM. I used `npmrc` to manage my NPM identities
(`npm i npmrc -g` to install ). Then I created a new profile called `public` with
(`npmrc -c public`) and then switch to it with `npmrc public`.
* create a pull request from `dev` to `main`
* check out `main`
* `npm version patch -m "message here" or minor`
* `npm publish --access public`
* Then switch to `dev` branch
* And then merge `main` into `dev` and push `dev` to origin
## License
MIT License
Copyright (c) 2021 Philip A Senger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
MIT © [psenger](https://github.com/psenger)