Browse Source

feat(core): iterate over linked list nodes instead of node values

pull/3359/head
Arman Ozak 7 years ago
parent
commit
026fb1defb
  1. 39
      npm/ng-packs/packages/core/src/lib/tests/linked-list.spec.ts
  2. 18
      npm/ng-packs/packages/core/src/lib/utils/linked-list.ts

39
npm/ng-packs/packages/core/src/lib/tests/linked-list.spec.ts

@ -212,7 +212,7 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "x" <-> "b" <-> "x" <-> "c" // "a" <-> "x" <-> "b" <-> "x" <-> "c"
const node1 = list.find(value => value === 'x'); const node1 = list.find(node => node.previous && node.previous.value === 'a');
expect(node1.value).toBe('x'); expect(node1.value).toBe('x');
expect(node1.previous.value).toBe('a'); expect(node1.previous.value).toBe('a');
@ -220,7 +220,7 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "x" <-> "b" <-> "x" <-> "c" // "a" <-> "x" <-> "b" <-> "x" <-> "c"
const node2 = list.find((_, index) => index === 3); const node2 = list.find(node => node.next && node.next.value === 'c');
expect(node2.value).toBe('x'); expect(node2.value).toBe('x');
expect(node2.previous.value).toBe('b'); expect(node2.previous.value).toBe('b');
@ -228,9 +228,9 @@ describe('Linked List (Doubly)', () => {
}); });
it('should return undefined when list is empty', () => { it('should return undefined when list is empty', () => {
const node = list.find(value => value === 'x'); const found = list.find(node => node.value === 'x');
expect(node).toBeUndefined(); expect(found).toBeUndefined();
}); });
it('should return undefined when predicate finds no match', () => { it('should return undefined when predicate finds no match', () => {
@ -240,9 +240,9 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "b" <-> "c" // "a" <-> "b" <-> "c"
const node = list.find(value => value === 'x'); const found = list.find(node => node.value === 'x');
expect(node).toBeUndefined(); expect(found).toBeUndefined();
expect(list.length).toBe(3); expect(list.length).toBe(3);
expect(list.head.value).toBe('a'); expect(list.head.value).toBe('a');
expect(list.head.next.value).toBe('b'); expect(list.head.next.value).toBe('b');
@ -263,26 +263,19 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "x" <-> "b" <-> "x" <-> "c" // "a" <-> "x" <-> "b" <-> "x" <-> "c"
const index1 = list.findIndex(value => value === 'x'); const index1 = list.findIndex(node => node.previous && node.previous.value === 'a');
expect(index1).toBe(1); expect(index1).toBe(1);
// "a" <-> "x" <-> "b" <-> "x" <-> "c" // "a" <-> "x" <-> "b" <-> "x" <-> "c"
let timesFound = 0; const index2 = list.findIndex(node => node.next && node.next.value === 'c');
const index2 = list.findIndex(value => {
if (timesFound > 1) return false;
timesFound += Number(value === 'x');
return timesFound > 1;
});
expect(index2).toBe(3); expect(index2).toBe(3);
}); });
it('should return -1 when list is empty', () => { it('should return -1 when list is empty', () => {
const index = list.findIndex(value => value === 'x'); const index = list.findIndex(node => node.value === 'x');
expect(index).toBe(-1); expect(index).toBe(-1);
}); });
@ -294,7 +287,7 @@ describe('Linked List (Doubly)', () => {
// "a" <-> "b" <-> "c" // "a" <-> "b" <-> "c"
const index = list.findIndex(value => value === 'x'); const index = list.findIndex(node => node.value === 'x');
expect(index).toBe(-1); expect(index).toBe(-1);
expect(list.length).toBe(3); expect(list.length).toBe(3);
@ -309,9 +302,9 @@ describe('Linked List (Doubly)', () => {
describe('#forEach', () => { describe('#forEach', () => {
it('should call given function for each node of the list', () => { it('should call given function for each node of the list', () => {
list.add('a').tail(); const a = list.add('a').tail();
list.add('b').tail(); const b = list.add('b').tail();
list.add('c').tail(); const c = list.add('c').tail();
// "a" <-> "b" <-> "c" // "a" <-> "b" <-> "c"
@ -319,9 +312,9 @@ describe('Linked List (Doubly)', () => {
list.forEach(spy); list.forEach(spy);
expect(spy.mock.calls).toEqual([ expect(spy.mock.calls).toEqual([
['a', 0, list], [a, 0, list],
['b', 1, list], [b, 1, list],
['c', 2, list], [c, 2, list],
]); ]);
}); });

18
npm/ng-packs/packages/core/src/lib/utils/linked-list.ts

@ -68,13 +68,13 @@ export class LinkedList<T = any> {
} }
addAfter(value: T, previousValue: T, compareFn = compare): ListNode<T> { addAfter(value: T, previousValue: T, compareFn = compare): ListNode<T> {
const previous = this.find(currentValue => compareFn(currentValue, previousValue)); const previous = this.find(node => compareFn(node.value, previousValue));
return previous ? this.linkWith(value, previous, previous.next) : this.addTail(value); return previous ? this.linkWith(value, previous, previous.next) : this.addTail(value);
} }
addBefore(value: T, nextValue: T, compareFn = compare): ListNode<T> { addBefore(value: T, nextValue: T, compareFn = compare): ListNode<T> {
const next = this.find(currentValue => compareFn(currentValue, nextValue)); const next = this.find(node => compareFn(node.value, nextValue));
return next ? this.linkWith(value, next.previous, next) : this.addHead(value); return next ? this.linkWith(value, next.previous, next) : this.addHead(value);
} }
@ -148,7 +148,7 @@ export class LinkedList<T = any> {
} }
dropByValue(value: T, compareFn = compare): ListNode<T> | undefined { dropByValue(value: T, compareFn = compare): ListNode<T> | undefined {
const position = this.findIndex(currentValue => compareFn(currentValue, value)); const position = this.findIndex(node => compareFn(node.value, value));
if (position < 0) return undefined; if (position < 0) return undefined;
@ -203,7 +203,7 @@ export class LinkedList<T = any> {
find(predicate: ListIteratorFunction<T>): ListNode<T> | undefined { find(predicate: ListIteratorFunction<T>): ListNode<T> | undefined {
for (let current = this.first, position = 0; current; position += 1, current = current.next) { for (let current = this.first, position = 0; current; position += 1, current = current.next) {
if (predicate(current.value, position, this)) return current; if (predicate(current, position, this)) return current;
} }
return undefined; return undefined;
@ -211,7 +211,7 @@ export class LinkedList<T = any> {
findIndex(predicate: ListIteratorFunction<T>): number { findIndex(predicate: ListIteratorFunction<T>): number {
for (let current = this.first, position = 0; current; position += 1, current = current.next) { for (let current = this.first, position = 0; current; position += 1, current = current.next) {
if (predicate(current.value, position, this)) return position; if (predicate(current, position, this)) return position;
} }
return -1; return -1;
@ -219,7 +219,7 @@ export class LinkedList<T = any> {
forEach<R = boolean>(callback: ListIteratorFunction<T, R>) { forEach<R = boolean>(callback: ListIteratorFunction<T, R>) {
for (let node = this.first, position = 0; node; position += 1, node = node.next) { for (let node = this.first, position = 0; node; position += 1, node = node.next) {
callback(node.value, position, this); callback(node, position, this);
} }
} }
@ -228,13 +228,13 @@ export class LinkedList<T = any> {
} }
indexOf(value: T, compareFn = compare): number { indexOf(value: T, compareFn = compare): number {
return this.findIndex(currentValue => compareFn(currentValue, value)); return this.findIndex(node => compareFn(node.value, value));
} }
toArray(): T[] { toArray(): T[] {
const array = new Array(this.size); const array = new Array(this.size);
this.forEach((value, index) => (array[index!] = value)); this.forEach((node, index) => (array[index!] = node.value));
return array; return array;
} }
@ -253,7 +253,7 @@ export class LinkedList<T = any> {
} }
export type ListIteratorFunction<T = any, R = boolean> = ( export type ListIteratorFunction<T = any, R = boolean> = (
value: T, node: ListNode<T>,
index?: number, index?: number,
list?: LinkedList, list?: LinkedList,
) => R; ) => R;

Loading…
Cancel
Save