Skip to content

Commit 2434779

Browse files
🌱 initial: First implementation based on existing circular.
1 parent 43bc831 commit 2434779

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+9947
-18
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
:left_right_arrow: [@data-structure-algebra/doubly-linked-list](https://data-structure-algebra.github.io/doubly-linked-list)
22
==
33

4-
Doubly linked list for JavaScript.
4+
Doubly linked lists for JavaScript.
55
See [docs](https://data-structure-algebra.github.io/doubly-linked-list/index.html).
6-
7-
> :building_construction: Caveat emptor! This is work in progress. Code may be
8-
> working. Documentation may be present. Coherence may be. Maybe.
6+
Parent is [js-data-structures](https://github.com/make-github-pseudonymous-again/js-data-structures).
97

108
> :warning: Depending on your environment, the code may require
119
> `regeneratorRuntime` to be defined, for instance by importing
1210
> [regenerator-runtime/runtime](https://www.npmjs.com/package/regenerator-runtime).
1311
12+
```js
13+
import {from} from '@data-structure-algebra/doubly-linked-list';
14+
let list = from('abc');
15+
```
16+
1417
[![License](https://img.shields.io/github/license/data-structure-algebra/doubly-linked-list.svg)](https://raw.githubusercontent.com/data-structure-algebra/doubly-linked-list/main/LICENSE)
1518
[![Version](https://img.shields.io/npm/v/@data-structure-algebra/doubly-linked-list.svg)](https://www.npmjs.org/package/@data-structure-algebra/doubly-linked-list)
1619
[![Tests](https://img.shields.io/github/workflow/status/data-structure-algebra/doubly-linked-list/ci?event=push&label=tests)](https://github.com/data-structure-algebra/doubly-linked-list/actions/workflows/ci.yml?query=branch:main)

doc/scripts/header.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ domReady(() => {
1717
header.insertBefore(projectname, header.firstChild);
1818

1919
const testlink = document.querySelector('header > a[data-ice="testLink"]');
20-
testlink.href = 'https://app.codecov.io/gh/data-structure-algebra/doubly-linked-list';
20+
testlink.href =
21+
'https://app.codecov.io/gh/data-structure-algebra/doubly-linked-list';
2122
testlink.target = '_BLANK';
2223

2324
const searchBox = document.querySelector('.search-box');

package.json

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"test:dist": "npm run test:modern && npm run test:module && npm run test:cjs",
6767
"test:modern": "IMPORT_MAP_PATH=test/import-maps/dist/index.modern.json npm run test-cmd",
6868
"test:module": "IMPORT_MAP_PATH=test/import-maps/dist/index.module.json npm run test-cmd",
69-
"test:src": "IMPORT_MAP_PATH=test/import-maps/src/index.json npm run test-cmd"
69+
"test:src": "IMPORT_MAP_PATH=test/import-maps/src/index.json npm run test-cmd --"
7070
},
7171
"dependencies": {},
7272
"devDependencies": {
@@ -75,6 +75,9 @@
7575
"@babel/plugin-transform-for-of": "7.18.8",
7676
"@babel/preset-env": "7.19.4",
7777
"@commitlint/cli": "17.1.2",
78+
"@iterable-iterator/list": "^1.0.1",
79+
"@iterable-iterator/map": "^1.0.1",
80+
"@iterable-iterator/range": "^2.1.0",
7881
"@js-library/commitlint-config": "0.0.4",
7982
"@node-loader/babel": "2.0.1",
8083
"@node-loader/core": "2.0.0",
@@ -208,16 +211,9 @@
208211
"unicorn"
209212
],
210213
"rules": {
214+
"camelcase": "off",
211215
"unicorn/prefer-node-protocol": "off",
212-
"unicorn/filename-case": [
213-
"error",
214-
{
215-
"cases": {
216-
"camelCase": true,
217-
"pascalCase": true
218-
}
219-
}
220-
]
216+
"unicorn/filename-case": "off"
221217
},
222218
"overrides": [
223219
{

src/Node.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Base node class.
3+
*
4+
* @class
5+
* @param {any} value The value to hold.
6+
*/
7+
export default function Node(value) {
8+
/** @member {any} The value/key held by this node. */
9+
this.value = value;
10+
/** @member {Node} Pointer to previous (left) sibling */
11+
this.prev = null;
12+
/** @member {Node} Pointer to next (right) sibling */
13+
this.next = null;
14+
}

src/_concat.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import assert from 'assert';
2+
import Node from './Node.js';
3+
4+
/**
5+
* Concatenate two input lists.
6+
*
7+
* @param {Node} z Last node of first input list.
8+
* @param {Node} y First node of second input list.
9+
*/
10+
export default function _concat(z, y) {
11+
assert(z instanceof Node && z.next === null);
12+
assert(y instanceof Node && y.prev === null);
13+
z.next = y;
14+
y.prev = z;
15+
}

src/_iter.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import assert from 'assert';
2+
import Node from './Node.js';
3+
4+
/**
5+
* Generator of nodes in list in order. You are allowed to edit the current
6+
* node.
7+
*
8+
* /!\ Modifying the next pointer of the current node will NOT change which
9+
* node comes next in the iteration.
10+
*
11+
* @param {Node} first First node of the list.
12+
* @return {IterableIterator<Node>} Yields nodes of a list in order.
13+
*/
14+
export default function* _iter(first) {
15+
assert(first instanceof Node);
16+
let next = first;
17+
18+
do {
19+
const x = next;
20+
next = x.next; // Compute next before yielding.
21+
yield x; // Necessary ?
22+
} while (next !== null);
23+
}

src/_iter_fast.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import assert from 'assert';
2+
import Node from './Node.js';
3+
4+
/**
5+
* Generator of nodes in list in order. The list cannot be empty. You should
6+
* not modify the current node's next pointer unless you know what you are
7+
* doing.
8+
*
9+
* /!\ Modifying the next pointer of the current node will change which node
10+
* comes next in the iteration.
11+
*
12+
* @param {Node} first First node of the list.
13+
* @return {IterableIterator<Node>} Yields nodes of a list in order.
14+
*/
15+
export default function* _iter_fast(first) {
16+
assert(first instanceof Node);
17+
let next = first;
18+
19+
do {
20+
yield next;
21+
next = next.next;
22+
} while (next !== null);
23+
}

src/_last.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import assert from 'assert';
2+
import Node from './Node.js';
3+
4+
/**
5+
* Returns the last node of a list. The list cannot be empty.
6+
*
7+
* @param {Node} first First node of the list.
8+
* @return {Node} Last node of the list.
9+
*/
10+
export default function _last(first) {
11+
assert(first instanceof Node);
12+
let next = first;
13+
14+
while (next.next !== null) {
15+
next = next.next;
16+
}
17+
18+
return next;
19+
}

src/_len.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import assert from 'assert';
2+
import Node from './Node.js';
3+
4+
/**
5+
* Compute the length of a non-empty list.
6+
*
7+
* @param {Node} x First node of the input list.
8+
* @return {number} The length of the input list.
9+
*/
10+
// eslint-disable-next-line unicorn/prevent-abbreviations
11+
export default function _len(x) {
12+
assert(x instanceof Node);
13+
let n = 1;
14+
let y = x.next;
15+
while (y !== null) {
16+
++n;
17+
y = y.next;
18+
}
19+
20+
return n;
21+
}

src/_pop.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import assert from 'assert';
2+
import Node from './Node.js';
3+
4+
/**
5+
* Removes last {@link Node} from a non-empty list.
6+
*
7+
* @param {Node} x Last node (not null). Cannot be the first node.
8+
* @return {Node} Last node of new list (not null).
9+
*/
10+
export default function _pop(x) {
11+
assert(x instanceof Node);
12+
assert(x.next === null);
13+
const prev = x.prev; // eslint-disable-line unicorn/prevent-abbreviations
14+
assert(prev !== null);
15+
prev.next = null;
16+
return prev;
17+
}

0 commit comments

Comments
 (0)