round-robin-js
Advanced tools
Comparing version 1.0.2 to 2.0.0
@@ -8,12 +8,23 @@ # Changelog | ||
## [Unreleased] | ||
## [1.0.2] - 2021-JUN-24 | ||
## [2.0.0] - 2022-feb-09 | ||
### Changed | ||
- deleteByKey to delete item by its key | ||
- deleteByValue to delete items by a matching criteria. | ||
- internal cleanup. | ||
## [1.0.2] - 2021-jun-24 | ||
### Fixed | ||
- index.d.ts | ||
## [1.0.1] - 2021-MAY-12 | ||
## [1.0.2] - 2021-jun-24 | ||
### Fixed | ||
- index.d.ts | ||
## [1.0.1] - 2021-may-12 | ||
### Fixed | ||
- README | ||
## [1.0.0] - 2021-MAY-12 | ||
## [1.0.0] - 2021-may-12 | ||
### Added | ||
- v1 |
{ | ||
"name": "round-robin-js", | ||
"version": "1.0.2", | ||
"version": "2.0.0", | ||
"description": "an implementation of round robin as a data structure", | ||
@@ -23,3 +23,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"@datastructures-js/linked-list": "^5.0.1" | ||
"@datastructures-js/linked-list": "^5.1.1" | ||
}, | ||
@@ -26,0 +26,0 @@ "devDependencies": { |
@@ -17,4 +17,4 @@ # round-robin-js | ||
* [next()](#next) | ||
* [completedRounds()](#completedrounds) | ||
* [delete(key)](#deletekey) | ||
* [deleteByKey(key)](#deletebykeykey) | ||
* [deleteByValue(cb)](#deletebyvaluecb) | ||
* [reset()](#reset) | ||
@@ -185,4 +185,4 @@ * [clear()](#clear) | ||
### completedRounds() | ||
returns the number of completed rounds. | ||
### deleteByKey(key) | ||
deletes an item by its key from the table. | ||
@@ -194,3 +194,3 @@ <table> | ||
<tr> | ||
<td align="center">number</td> | ||
<td align="center">boolean</td> | ||
</tr> | ||
@@ -200,16 +200,26 @@ </table> | ||
```js | ||
console.log(sequentialTable.completedRounds()); // 1 | ||
sequentialTable.deleteByKey(0); | ||
sequentialTable.deleteByKey(2); | ||
console.log(sequentialTable.next()); // { key: 1, value: 'T2' } | ||
console.log(sequentialTable.next()); // { key: 3, value: 'T4' } | ||
console.log(sequentialTable.next()); // { key: 1, value: 'T2' } | ||
console.log(randomTable.completedRounds()); // 1 | ||
randomTable.deleteByKey(0); | ||
randomTable.deleteByKey(2); | ||
console.log(randomTable.next()); // { key: 3, value: 25 } | ||
console.log(randomTable.next()); // { key: 1, value: 10 } | ||
console.log(randomTable.next()); // { key: 3, value: 25 } | ||
``` | ||
### delete(key) | ||
deletes an item from the table by its key. | ||
### deleteByValue(cb) | ||
deletes items with values that match a criteria from the table and returns the number of deleted items. | ||
<table> | ||
<tr> | ||
<th align="center">params</th> | ||
<th align="center">return</th> | ||
</tr> | ||
<tr> | ||
<td align="center">boolean</td> | ||
<td align="center">cb: (value: T) => boolean</td> | ||
<td align="center">number</td> | ||
</tr> | ||
@@ -219,17 +229,21 @@ </table> | ||
```js | ||
sequentialTable.delete(0); | ||
sequentialTable.delete(2); | ||
console.log(sequentialTable.next()); // { key: 1, value: 'T2' } | ||
console.log(sequentialTable.next()); // { key: 3, value: 'T4' } | ||
console.log(sequentialTable.next()); // { key: 1, value: 'T2' } | ||
const seqTable = new SequentialRoundRobin<number>([2, 3, 5, 6, 7, 10]); | ||
const ranTable = new RandomRoundRobin<{ id: string }>([ | ||
{ id: '123' }, | ||
{ id: 'id456' }, | ||
{ id: '456' }, | ||
{ id: 'id780' } | ||
]); | ||
randomTable.delete(0); | ||
randomTable.delete(2); | ||
console.log(randomTable.next()); // { key: 3, value: 25 } | ||
console.log(randomTable.next()); // { key: 1, value: 10 } | ||
console.log(randomTable.next()); // { key: 3, value: 25 } | ||
const d1 = seqTable.deleteByValue((n) => n % 2 === 1); // 3 | ||
console.log(seqTable.next(), seqTable.next(), seqTable.next()) | ||
// { key: 0, value: 2 } { key: 3, value: 6 } { key: 5, value: 10 } | ||
const d2 = ranTable.deleteByValue((obj) => obj.id.indexOf('id') === 0); // 2 | ||
console.log(ranTable.next(), ranTable.next()) | ||
// { key: 2, value: { id: '456' } } { key: 0, value: { id: '123' } } | ||
``` | ||
### reset() | ||
resets the table with the intial items and clears completed rounds. | ||
resets the table with the intial values. | ||
@@ -239,7 +253,5 @@ ```js | ||
console.log(sequentialTable.count()); // 3 | ||
console.log(sequentialTable.completedRounds()); // 0 | ||
randomTable.reset(); | ||
console.log(randomTable.count()); // 3 | ||
console.log(randomTable.completedRounds()); // 0 | ||
``` | ||
@@ -253,7 +265,5 @@ | ||
console.log(sequentialTable.count()); // 0 | ||
console.log(sequentialTable.completedRounds()); // 0 | ||
randomTable.clear(); | ||
console.log(randomTable.count()); // 0 | ||
console.log(randomTable.completedRounds()); // 0 | ||
``` | ||
@@ -260,0 +270,0 @@ |
@@ -15,6 +15,6 @@ /** | ||
* @constructor | ||
* @param {array} items | ||
* @param {array} values | ||
*/ | ||
constructor(items) { | ||
super(items); | ||
constructor(values) { | ||
super(values); | ||
this._init(); | ||
@@ -28,16 +28,14 @@ } | ||
this._items = new Map(); | ||
this._keys = new Set(); | ||
this._round = new Set(); | ||
this._initialItems.forEach((item) => this.add(item)); | ||
this._initialValues.forEach((value) => this.add(value)); | ||
} | ||
/** | ||
* Adds an item and memoizes its key for random selection | ||
* Adds a value to the table | ||
* @public | ||
* @return {object} | ||
* @return {any} value | ||
*/ | ||
add(item) { | ||
add(value) { | ||
const key = this._currentkey; | ||
this._items.set(key, { key, value: item }); | ||
this._keys.add(key); | ||
this._items.set(key, { key, value }); | ||
this._currentkey++; | ||
@@ -48,3 +46,3 @@ return this._items.get(key); | ||
/** | ||
* Deletes an item with its key from the table | ||
* Deletes an item by its key from the table | ||
* @public | ||
@@ -54,4 +52,4 @@ * @param {number} key | ||
*/ | ||
delete(key) { | ||
if (!this._keys.has(key)) { | ||
deleteByKey(key) { | ||
if (!this._items.has(key)) { | ||
return false; | ||
@@ -61,11 +59,6 @@ } | ||
if (this._currentTurn && this._currentTurn.key === key) { | ||
this._currentTurn = this._selectNextItem(); | ||
if (this._currentTurn === null) { | ||
this._completedRounds += 1; | ||
} | ||
this._currentTurn = this._nextTurn(); | ||
} | ||
this._keys.delete(key); | ||
this._round.delete(key); | ||
return this._items.delete(key); | ||
@@ -75,2 +68,19 @@ } | ||
/** | ||
* Deletes items that their values match a criteria | ||
* @public | ||
* @param {function} cb | ||
* @return {number} | ||
*/ | ||
deleteByValue(cb) { | ||
let deleted = 0; | ||
this._items.forEach(({ key, value }) => { | ||
if (cb(value)) { | ||
this.deleteByKey(key); | ||
deleted += 1; | ||
} | ||
}); | ||
return deleted; | ||
} | ||
/** | ||
* Selects the next item's key from the round | ||
@@ -80,15 +90,16 @@ * @public | ||
*/ | ||
_selectNextItem() { | ||
_nextTurn() { | ||
if (this._currentTurn === null) { | ||
this._round = new Set(this._keys); | ||
const keys = Array.from(this._items.keys()); | ||
this._round = new Set(keys); | ||
} | ||
const keys = Array.from(this._round); | ||
if (keys.length === 0) { | ||
if (this._round.size === 0) { | ||
return null; | ||
} | ||
const randomKey = keys[Math.floor(Math.random() * keys.length)]; | ||
this._round.delete(randomKey); | ||
return this._items.get(randomKey); | ||
const roundKeys = Array.from(this._round); | ||
const selectedKey = roundKeys[Math.floor(Math.random() * roundKeys.length)]; | ||
this._round.delete(selectedKey); | ||
return this._items.get(selectedKey); | ||
} | ||
@@ -107,11 +118,7 @@ | ||
if (this._currentTurn === null) { | ||
this._currentTurn = this._selectNextItem(); | ||
this._currentTurn = this._nextTurn(); | ||
} | ||
const item = this._currentTurn; | ||
this._currentTurn = this._selectNextItem(); | ||
if (this._currentTurn === null) { | ||
this._completedRounds += 1; | ||
} | ||
this._currentTurn = this._nextTurn(); | ||
return item; | ||
@@ -118,0 +125,0 @@ } |
@@ -7,5 +7,6 @@ export interface RoundRobinItem<T> { | ||
export class RoundRobin<T> { | ||
constructor(items?: T[]); | ||
add(item: T): RoundRobinItem<T>; | ||
delete(key: number): boolean; | ||
constructor(values?: T[]); | ||
add(value: T): RoundRobinItem<T>; | ||
deleteByKey(key: number): boolean; | ||
deleteByValue(cb: (value: T) => boolean): number; | ||
next(): RoundRobinItem<T>; | ||
@@ -12,0 +13,0 @@ count(): number; |
@@ -15,11 +15,11 @@ /** | ||
* @constructor | ||
* @param {array} items | ||
* @param {array} values | ||
*/ | ||
constructor(items = []) { | ||
if (items && !Array.isArray(items)) { | ||
throw new Error('items must be an array'); | ||
constructor(values = []) { | ||
if (values && !Array.isArray(values)) { | ||
throw new Error('RoundRobin constructor: values must be an array'); | ||
} | ||
this._initialItems = items; | ||
this._initialValues = values; | ||
this._currentkey = 0; | ||
this._completedRounds = 0; | ||
this._currentTurn = null; | ||
@@ -29,11 +29,2 @@ } | ||
/** | ||
* Returns number of completed round of turns | ||
* @public | ||
* @return {number} | ||
*/ | ||
completedRounds() { | ||
return this._completedRounds; | ||
} | ||
/** | ||
* Clears the table | ||
@@ -45,3 +36,2 @@ * @public | ||
this._currentkey = 0; | ||
this._completedRounds = 0; | ||
this._currentTurn = null; | ||
@@ -48,0 +38,0 @@ return this; |
@@ -16,6 +16,6 @@ /** | ||
* @constructor | ||
* @param {array} items | ||
* @param {array} values | ||
*/ | ||
constructor(items) { | ||
super(items); | ||
constructor(values) { | ||
super(values); | ||
this._init(); | ||
@@ -30,3 +30,3 @@ } | ||
this._itemNodes = new Map(); | ||
this._initialItems.forEach((item) => this.add(item)); | ||
this._initialValues.forEach((value) => this.add(value)); | ||
} | ||
@@ -37,9 +37,9 @@ | ||
* @public | ||
* @param {any} item | ||
* @return {object} | ||
* @param {any} value | ||
* @return {any} | ||
*/ | ||
add(item) { | ||
add(value) { | ||
this._itemNodes.set( | ||
this._currentkey, | ||
this._items.insertLast({ key: this._currentkey++, value: item }) | ||
this._items.insertLast({ key: this._currentkey++, value }) | ||
); | ||
@@ -50,3 +50,3 @@ return this._items.tail().getValue(); | ||
/** | ||
* Deletes an item from the table | ||
* Deletes an item by its key from the table | ||
* @public | ||
@@ -56,3 +56,3 @@ * @param {number} key | ||
*/ | ||
delete(key) { | ||
deleteByKey(key) { | ||
if (!this._itemNodes.has(key)) { | ||
@@ -64,5 +64,2 @@ return false; | ||
this._currentTurn = this._currentTurn.getNext(); | ||
if (this._currentTurn === null) { | ||
this._completedRounds += 1; | ||
} | ||
} | ||
@@ -75,2 +72,20 @@ | ||
/** | ||
* Deletes items that their values match a criteria | ||
* @public | ||
* @param {function} cb | ||
* @return {number} | ||
*/ | ||
deleteByValue(cb) { | ||
const deletedKeys = []; | ||
this._items.forEach((itemNode) => { | ||
const { key, value } = itemNode.getValue(); | ||
if (cb(value)) { | ||
deletedKeys.push(key); | ||
} | ||
}); | ||
deletedKeys.map((key) => this.deleteByKey(key)); | ||
return deletedKeys.length; | ||
} | ||
/** | ||
* Selects the next item in the turn round sequentially | ||
@@ -91,6 +106,2 @@ * @public | ||
this._currentTurn = this._currentTurn.getNext(); | ||
if (this._currentTurn === null) { | ||
this._completedRounds += 1; | ||
} | ||
return item; | ||
@@ -97,0 +108,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16345
318
271