digital-chain
Advanced tools
Comparing version 3.7.0 to 3.8.0
90
index.js
@@ -31,3 +31,3 @@ /** | ||
push(item) { | ||
let node = new ListNode(item, this) | ||
let node = this._newListNode(item, this) | ||
@@ -103,3 +103,3 @@ if (this._length > 0) { | ||
unshift(item) { | ||
let node = new ListNode(item, this) | ||
let node = this._newListNode(item, this) | ||
@@ -309,3 +309,3 @@ if (this._length > 0) { | ||
/** | ||
* sort the list | ||
* sort the list | ||
* | ||
@@ -348,3 +348,3 @@ * the default sorting comparator is: | ||
* ``` | ||
* @return {ListNodeIterator} | ||
* @return {NodeIterator} | ||
* | ||
@@ -354,3 +354,3 @@ * @public | ||
nodes() { | ||
return new NodeIterator(this) | ||
return this._newNodeIterator(this) | ||
} | ||
@@ -371,3 +371,3 @@ | ||
values() { | ||
return new ValueIterator(this) | ||
return this._newValueIterator(this) | ||
} | ||
@@ -388,3 +388,3 @@ | ||
[Symbol.iterator]() { | ||
return new EntryIterator(this) | ||
return this._newEntryIterator(this) | ||
} | ||
@@ -400,3 +400,3 @@ | ||
reverseIterator() { | ||
return new EntryIterator(this, FROM_TAIL) | ||
return this._newEntryIterator(this, FROM_TAIL) | ||
} | ||
@@ -510,5 +510,4 @@ | ||
/** | ||
* A functional iterator over the nodes in the list, prefer the new ES6 iteration methods over this | ||
* A functional iterator over the nodes in the list, prefer the new ES6 iteration methods over this | ||
* | ||
* @return {[type]} | ||
*/ | ||
@@ -526,2 +525,6 @@ nodeIterator() { | ||
/** | ||
* A functional iterator over the values in the list, prefer the new ES6 iteration methods over this | ||
* | ||
*/ | ||
iterator() { | ||
@@ -537,2 +540,18 @@ let next = this.head | ||
} | ||
_newEntryIterator(list, direction) { | ||
return new EntryIterator(list, direction) | ||
} | ||
_newValueIterator(list) { | ||
return new ValueIterator(list) | ||
} | ||
_newNodeIterator(list) { | ||
return new NodeIterator(list) | ||
} | ||
_newListNode(data, parent) { | ||
return new ListNode(data, parent) | ||
} | ||
} | ||
@@ -543,2 +562,18 @@ | ||
/** | ||
* Implements iteration over the list's entries (pairs of value + it's hosting node). | ||
* This iterator is the only iterator that can change it's direction, the others are | ||
* provided for convenience and only iterate from head to tail. | ||
* | ||
* ```js | ||
* const list = new LinkedList() | ||
* | ||
* // iterate from head to tail | ||
* for (const [value, node] of list) { ... } | ||
* | ||
* // iterate from tail to head | ||
* for (const [value, node] of list.reverseIterator()) { ... } | ||
* ``` | ||
* | ||
*/ | ||
class EntryIterator { | ||
@@ -588,2 +623,14 @@ constructor(list, direction) { | ||
/** | ||
* Implements iteration over the list's values. | ||
* | ||
* ```js | ||
* const list = new LinkedList() | ||
* | ||
* // iterate from head to tail | ||
* for (const value of list.values()) { ... } | ||
* | ||
* ``` | ||
* | ||
*/ | ||
class ValueIterator extends EntryIterator { | ||
@@ -599,2 +646,14 @@ constructor(list) { | ||
/** | ||
* Implements iteration over the list's nodes. | ||
* | ||
* ```js | ||
* const list = new LinkedList() | ||
* | ||
* // iterate from head to tail | ||
* for (const node of list.nodes()) { ... } | ||
* | ||
* ``` | ||
* | ||
*/ | ||
class NodeIterator extends EntryIterator { | ||
@@ -629,2 +688,11 @@ constructor(list) { | ||
module.exports = LinkedList | ||
LinkedList.EntryIterator = EntryIterator | ||
LinkedList.ValueIterator = ValueIterator | ||
LinkedList.NodeIterator = NodeIterator | ||
LinkedList.ListNode = ListNode | ||
LinkedList.direction = Object.freeze({ | ||
FROM_HEAD, | ||
FROM_TAIL | ||
}) | ||
module.exports = LinkedList |
{ | ||
"name": "digital-chain", | ||
"version": "3.7.0", | ||
"version": "3.8.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
124
README.md
@@ -32,2 +32,3 @@ # digital-chain [![Build Status](https://secure.travis-ci.org/kessler/digital-chain.png?branch=master)](http://travis-ci.org/kessler/digital-chain) [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) | ||
* [iterator](#iterator) | ||
* [iterator](#iterator-1) | ||
* [reverseIterator](#reverseiterator) | ||
@@ -43,4 +44,10 @@ * [findFirst](#findfirst) | ||
* [nodeIterator](#nodeiterator) | ||
* [EntryIterator](#entryiterator) | ||
* [Parameters](#parameters-11) | ||
* [ValueIterator](#valueiterator) | ||
* [Parameters](#parameters-12) | ||
* [NodeIterator](#nodeiterator-1) | ||
* [Parameters](#parameters-13) | ||
* [ListNode](#listnode) | ||
* [Parameters](#parameters-11) | ||
* [Parameters](#parameters-14) | ||
@@ -180,3 +187,3 @@ ### LinkedList | ||
Returns **ListNodeIterator** | ||
Returns **[NodeIterator](#nodeiterator)** | ||
@@ -193,3 +200,3 @@ #### values | ||
Returns **ValueIterator** | ||
Returns **[ValueIterator](#valueiterator)** | ||
@@ -206,4 +213,8 @@ #### iterator | ||
Returns **EntryIterator** | ||
Returns **[EntryIterator](#entryiterator)** | ||
#### iterator | ||
A functional iterator over the values in the list, prefer the new ES6 iteration methods over this | ||
#### reverseIterator | ||
@@ -213,3 +224,3 @@ | ||
Returns **EntryIterator** | ||
Returns **[EntryIterator](#entryiterator)** | ||
@@ -263,4 +274,59 @@ #### findFirst | ||
Returns **\[type]** | ||
### EntryIterator | ||
Implements iteration over the list's entries (pairs of value + it's hosting node). | ||
This iterator is the only iterator that can change it's direction, the others are | ||
provided for convenience and only iterate from head to tail. | ||
```js | ||
const list = new LinkedList() | ||
// iterate from head to tail | ||
for (const [value, node] of list) { ... } | ||
// iterate from tail to head | ||
for (const [value, node] of list.reverseIterator()) { ... } | ||
``` | ||
#### Parameters | ||
* `list` | ||
* `direction` | ||
### ValueIterator | ||
**Extends EntryIterator** | ||
Implements iteration over the list's values. | ||
```js | ||
const list = new LinkedList() | ||
// iterate from head to tail | ||
for (const value of list.values()) { ... } | ||
``` | ||
#### Parameters | ||
* `list` | ||
### NodeIterator | ||
**Extends EntryIterator** | ||
Implements iteration over the list's nodes. | ||
```js | ||
const list = new LinkedList() | ||
// iterate from head to tail | ||
for (const node of list.nodes()) { ... } | ||
``` | ||
#### Parameters | ||
* `list` | ||
### ListNode | ||
@@ -275,4 +341,50 @@ | ||
## Extension | ||
This implemenation uses several internal classes for iteration and for "hosting" values. | ||
### EntryIterator, ValueIterator, NodeIterator and ListNode | ||
These classes can be customized via inheritance: | ||
```js | ||
const LinkedList = require('digital-chain') | ||
class MyEntryIterator extends LinkedList.EntryIterator {} | ||
class MyValueIterator extends LinkedList.ValueIterator {} | ||
class MyNodeIterator extends LinkedList.NodeIterator {} | ||
class MyListNode extends LinkedList.ListNode {} | ||
``` | ||
These new classes can then be incorporated into the linked list's by overriding their respective factory methods: | ||
```js | ||
class MyLinkedList extends LinkedList { | ||
_newEntryIterator(list, direction) { | ||
return new MyEntryIterator(list, direction) // direction constants are LinkedList.FROM_HEAD or LinkedList.FROM_TAIL | ||
} | ||
_newValueIterator(list) { | ||
return new MyValueIterator(list) | ||
} | ||
_newNodeIterator(list) { | ||
return new MyNodeIterator(list) | ||
} | ||
_newListNode(data, parent) { | ||
return new MyListNode(data, parent) | ||
} | ||
} | ||
// of course this can also be done to an existing instance: | ||
const customList = new LinkedList() | ||
customList._newEntryIterator = (list, direction) => new MyEntryIterator(list, direction) | ||
``` | ||
## docs | ||
documentation readme index.js --section=API |
40
test.js
@@ -239,3 +239,2 @@ const LinkedList = require('./index') | ||
describe('pop', () => { | ||
@@ -773,2 +772,41 @@ it('from a list with one node', () => { | ||
describe('replace internal classes with inheritance', () => { | ||
it('EntryIterator', () => { | ||
class MyEntryIterator extends LinkedList.EntryIterator {} | ||
topic._newEntryIterator = (list, direction) => new MyEntryIterator(list, direction) | ||
const iterator = topic[Symbol.iterator]() | ||
expect(iterator).to.be.instanceOf(MyEntryIterator) | ||
}) | ||
it('ValueIterator', () => { | ||
class MyValueIterator extends LinkedList.ValueIterator {} | ||
topic._newValueIterator = (list) => new MyValueIterator(list) | ||
const iterator = topic.values() | ||
expect(iterator).to.be.instanceOf(MyValueIterator) | ||
}) | ||
it('NodeIterator', () => { | ||
class MyNodeIterator extends LinkedList.NodeIterator {} | ||
topic._newNodeIterator = (list) => new MyNodeIterator(list) | ||
const iterator = topic.nodes() | ||
expect(iterator).to.be.instanceOf(MyNodeIterator) | ||
}) | ||
it('ListNode', () => { | ||
class MyListNode extends LinkedList.ListNode { } | ||
topic._newListNode = (data, parent) => new MyListNode(data, parent) | ||
const node = topic.push(1) | ||
expect(node).to.be.instanceOf(MyListNode) | ||
}) | ||
}) | ||
it.skip('bench', () => { | ||
@@ -775,0 +813,0 @@ |
44835
1265
383