diff --git a/README.md b/README.md index 626fc5e..8dee570 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,23 @@ let result = list.toArray() result // => [4, 5, 6, 7] ``` +#### LinkedList.concat(): LinkedList + +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. diff --git a/src/index.ts b/src/index.ts index d3dfea6..351db14 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,6 +41,45 @@ export class LinkedList { 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(listA: LinkedList, listB: LinkedList, listAEnd: 'head' | 'tail', listBEnd: 'head' | 'tail'): LinkedList { + 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 { diff --git a/test/LinkedListTest.ts b/test/LinkedListTest.ts index c7fa67d..3205d7d 100644 --- a/test/LinkedListTest.ts +++ b/test/LinkedListTest.ts @@ -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[] = [];