Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,23 @@ let result = list.toArray()
result // => [4, 5, 6, 7]
```

#### LinkedList<T>.concat(): LinkedList<T>

Allows you to concatenate two linked lists using either their heads or tails respectively.

```typescript
const listA = new LinkedList(1, 2);
const listB = new LinkedList(-1, -2);
const headAToHeadB = LinkedList.concat(listA, listB, 'head', 'head').toArray();
// => [ 2, 1, -1, -2 ]
const headAToTailB = LinkedList.concat(listA, listB, 'head', 'tail').toArray();
// => [ -1, -2, 1, 2 ]
const tailAToHeadB = LinkedList.concat(listA, listB, 'tail', 'head').toArray();
// => [ 1, 2, -1, -2 ]
const tailAToTailB = LinkedList.concat(listA, listB, 'tail', 'tail').toArray();
// => [ 1, 2, -2, -1 ]
```

## Attribution

This linked-list was originally shared by Christos Monogios via his [blog][blog]. The [original code][origcode] has been modified and extended to support typedef generics to allow for type checking on stored values for linked lists and iterable and iterator protocols.
Expand Down
39 changes: 39 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,45 @@ export class LinkedList<T> {
return this._length;
}

/**
* Given two lists, it concatenates them as configured and returns a single linked list.
*
* @param listA linked list a
* @param listB linked list b
* @param listAEnd use head or tail of listA for the joint
* @param listBEnd use head or tail of listB for the joint
*
* @example ```ts
* const listA = new LinkedList(1, 2);
* const listB = new LinkedList(-1, -2);
* const headAToHeadB = LinkedList.concat(listA, listB, 'head', 'head').toArray();
* // => [ 2, 1, -1, -2 ]
* const headAToTailB = LinkedList.concat(listA, listB, 'head', 'tail').toArray();
* // => [ -1, -2, 1, 2 ]
* const tailAToHeadB = LinkedList.concat(listA, listB, 'tail', 'head').toArray();
* // => [ 1, 2, -1, -2 ]
* const tailAToTailB = LinkedList.concat(listA, listB, 'tail', 'tail').toArray();
* // => [ 1, 2, -2, -1 ]
* ```
*/
static concat<T>(listA: LinkedList<T>, listB: LinkedList<T>, listAEnd: 'head' | 'tail', listBEnd: 'head' | 'tail'): LinkedList<T> {
const entriesA = listA.toArray();
const entriesB = listB.toArray();
if (listAEnd === 'head') {
if (listBEnd === 'head') {
entriesA.reverse();
return new LinkedList(...[...entriesA, ...entriesB]);
} else {
return new LinkedList(...[...entriesB, ...entriesA]);
}
} else {
if (listBEnd === 'tail') {
entriesB.reverse();
}
return new LinkedList(...[...entriesA, ...entriesB]);
}
}

// Adds the element at a specific position inside the linked list
insert(val: T, previousItem: T, checkDuplicates: boolean = false): boolean {

Expand Down
27 changes: 27 additions & 0 deletions test/LinkedListTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,33 @@ class Foo {
}

describe('Linked-List Tests', () => {

it('should concat lists', () => {
const listA = new LinkedList(1, 2);
const listB = new LinkedList(-1, -2);
const headAToHeadB = LinkedList.concat(listA, listB, 'head', 'head').toArray();
expect(headAToHeadB[0]).to.equal(2);
expect(headAToHeadB[1]).to.equal(1);
expect(headAToHeadB[2]).to.equal(-1);
expect(headAToHeadB[3]).to.equal(-2);
const headAToTailB = LinkedList.concat(listA, listB, 'head', 'tail').toArray();
expect(headAToTailB[0]).to.equal(-1);
expect(headAToTailB[1]).to.equal(-2);
expect(headAToTailB[2]).to.equal(1);
expect(headAToTailB[3]).to.equal(2);
const tailAToHeadB = LinkedList.concat(listA, listB, 'tail', 'head').toArray();
expect(tailAToHeadB[0]).to.equal(1);
expect(tailAToHeadB[1]).to.equal(2);
expect(tailAToHeadB[2]).to.equal(-1);
expect(tailAToHeadB[3]).to.equal(-2);
const tailAToTailB = LinkedList.concat(listA, listB, 'tail', 'tail').toArray();
expect(tailAToTailB[0]).to.equal(1);
expect(tailAToTailB[1]).to.equal(2);
expect(tailAToTailB[2]).to.equal(-2);
expect(tailAToTailB[3]).to.equal(-1);
})


it('should create an empty list #1', () => {
let values: number[] = [];

Expand Down