diff --git a/index.d.ts b/index.d.ts index 7385b3d..42ef8aa 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,5 @@ export declare type Comparator = (a: T, b: T) => number; +export declare type Criteria = (val: T) => boolean; export default class TinyQueue { public data : T[]; @@ -7,4 +8,5 @@ export default class TinyQueue { peek () : T | undefined; pop () : T | undefined; push (item: T) : void; + update (newItem: T, criteria? : Criteria); } diff --git a/index.js b/index.js index 21cff98..bbe9391 100644 --- a/index.js +++ b/index.js @@ -33,6 +33,26 @@ export default class TinyQueue { return this.data[0]; } + update(newValue, criteria) { + let pos = this.data.findIndex(function(value, index, array) { + return criteria(value); + }); + if (pos >= 0) { + this.data[pos] = newValue; + let childPos = (pos << 1) + 1; + if (pos == 0) + this._down(pos); + else if (childPos >= this.length) + this._up(pos); + else if (this.compare(newValue, this.data[childPos]) < 0) + this._up(pos); + else if (this.compare(newValue, this.data[childPos]) > 0) + this._down(pos); + return true; + } + return false; + } + _up(pos) { const {data, compare} = this; const item = data[pos]; diff --git a/test.js b/test.js index e429c85..ece5cf7 100644 --- a/test.js +++ b/test.js @@ -58,3 +58,23 @@ test('handles init with empty array', (t) => { t.end(); }); + +test('updates few elements', (t) => { + const queue = new TinyQueue(); + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(1); + + let res = queue.update(4, (val) => { return val == 1 }); + t.equal(res, true); + t.equal(queue.length, 4); + t.equal(queue.peek(), 1); + + res = queue.update(4, (val) => { return val == 1 }); + t.equal(res, true); + t.equal(queue.length, 4); + t.equal(queue.peek(), 2); + + t.end(); +});