Skip to content

Commit 8e12906

Browse files
authored
Merge pull request #10 from eyas-ranjous/delete_by_value
add deleteByValue
2 parents f9e5895 + f6400b5 commit 8e12906

File tree

9 files changed

+172
-116
lines changed

9 files changed

+172
-116
lines changed

CHANGELOG.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8-
## [1.0.2] - 2021-JUN-24
8+
9+
## [2.0.0] - 2022-feb-09
10+
### Changed
11+
- deleteByKey to delete item by its key
12+
- deleteByValue to delete items by a matching criteria.
13+
- internal cleanup.
14+
15+
## [1.0.2] - 2021-jun-24
16+
### Fixed
17+
- index.d.ts
18+
19+
## [1.0.2] - 2021-jun-24
920
### Fixed
1021
- index.d.ts
1122

12-
## [1.0.1] - 2021-MAY-12
23+
## [1.0.1] - 2021-may-12
1324
### Fixed
1425
- README
1526

16-
## [1.0.0] - 2021-MAY-12
27+
## [1.0.0] - 2021-may-12
1728
### Added
1829
- v1

README.md

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ An implementation of the round robin as a data structure. Two strategies are imp
1414
* [add(item)](#additem)
1515
* [count()](#count)
1616
* [next()](#next)
17-
* [completedRounds()](#completedrounds)
18-
* [delete(key)](#deletekey)
17+
* [deleteByKey(key)](#deletebykeykey)
18+
* [deleteByValue(cb)](#deletebyvaluecb)
1919
* [reset()](#reset)
2020
* [clear()](#clear)
2121
* [Build](#build)
@@ -181,61 +181,73 @@ console.log(randomTable.next()); // { key: 3, value: 25 }
181181
console.log(randomTable.next()); // { key: 1, value: 10 }
182182
```
183183

184-
### completedRounds()
185-
returns the number of completed rounds.
184+
### deleteByKey(key)
185+
deletes an item by its key from the table.
186186

187187
<table>
188188
<tr>
189189
<th align="center">return</th>
190190
</tr>
191191
<tr>
192-
<td align="center">number</td>
192+
<td align="center">boolean</td>
193193
</tr>
194194
</table>
195195

196196
```js
197-
console.log(sequentialTable.completedRounds()); // 1
197+
sequentialTable.deleteByKey(0);
198+
sequentialTable.deleteByKey(2);
199+
console.log(sequentialTable.next()); // { key: 1, value: 'T2' }
200+
console.log(sequentialTable.next()); // { key: 3, value: 'T4' }
201+
console.log(sequentialTable.next()); // { key: 1, value: 'T2' }
198202

199-
console.log(randomTable.completedRounds()); // 1
203+
randomTable.deleteByKey(0);
204+
randomTable.deleteByKey(2);
205+
console.log(randomTable.next()); // { key: 3, value: 25 }
206+
console.log(randomTable.next()); // { key: 1, value: 10 }
207+
console.log(randomTable.next()); // { key: 3, value: 25 }
200208
```
201209

202-
### delete(key)
203-
deletes an item from the table by its key.
210+
### deleteByValue(cb)
211+
deletes items with values that match a criteria from the table and returns the number of deleted items.
204212

205213
<table>
206214
<tr>
215+
<th align="center">params</th>
207216
<th align="center">return</th>
208217
</tr>
209218
<tr>
210-
<td align="center">boolean</td>
219+
<td align="center">cb: (value: T) => boolean</td>
220+
<td align="center">number</td>
211221
</tr>
212222
</table>
213223

214224
```js
215-
sequentialTable.delete(0);
216-
sequentialTable.delete(2);
217-
console.log(sequentialTable.next()); // { key: 1, value: 'T2' }
218-
console.log(sequentialTable.next()); // { key: 3, value: 'T4' }
219-
console.log(sequentialTable.next()); // { key: 1, value: 'T2' }
220-
221-
randomTable.delete(0);
222-
randomTable.delete(2);
223-
console.log(randomTable.next()); // { key: 3, value: 25 }
224-
console.log(randomTable.next()); // { key: 1, value: 10 }
225-
console.log(randomTable.next()); // { key: 3, value: 25 }
225+
const seqTable = new SequentialRoundRobin<number>([2, 3, 5, 6, 7, 10]);
226+
const ranTable = new RandomRoundRobin<{ id: string }>([
227+
{ id: '123' },
228+
{ id: 'id456' },
229+
{ id: '456' },
230+
{ id: 'id780' }
231+
]);
232+
233+
const d1 = seqTable.deleteByValue((n) => n % 2 === 1); // 3
234+
console.log(seqTable.next(), seqTable.next(), seqTable.next())
235+
// { key: 0, value: 2 } { key: 3, value: 6 } { key: 5, value: 10 }
236+
237+
const d2 = ranTable.deleteByValue((obj) => obj.id.indexOf('id') === 0); // 2
238+
console.log(ranTable.next(), ranTable.next())
239+
// { key: 2, value: { id: '456' } } { key: 0, value: { id: '123' } }
226240
```
227241

228242
### reset()
229-
resets the table with the intial items and clears completed rounds.
243+
resets the table with the intial values.
230244

231245
```js
232246
sequentialTable.reset();
233247
console.log(sequentialTable.count()); // 3
234-
console.log(sequentialTable.completedRounds()); // 0
235248

236249
randomTable.reset();
237250
console.log(randomTable.count()); // 3
238-
console.log(randomTable.completedRounds()); // 0
239251
```
240252

241253
### clear()
@@ -244,11 +256,9 @@ clears all values in the table.
244256
```js
245257
sequentialTable.clear();
246258
console.log(sequentialTable.count()); // 0
247-
console.log(sequentialTable.completedRounds()); // 0
248259

249260
randomTable.clear();
250261
console.log(randomTable.count()); // 0
251-
console.log(randomTable.completedRounds()); // 0
252262
```
253263

254264
## Build

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "round-robin-js",
3-
"version": "1.0.2",
3+
"version": "2.0.0",
44
"description": "an implementation of round robin as a data structure",
55
"main": "index.js",
66
"scripts": {
@@ -20,7 +20,7 @@
2020
},
2121
"homepage": "https://github.com/eyas-ranjous/round-robin-js#readme",
2222
"dependencies": {
23-
"@datastructures-js/linked-list": "^5.0.1"
23+
"@datastructures-js/linked-list": "^5.1.1"
2424
},
2525
"devDependencies": {
2626
"chai": "^4.2.0",

src/RandomRoundRobin.js

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const RoundRobin = require('./RoundRobin');
1212
class RandomRoundRobin extends RoundRobin {
1313
/**
1414
* @constructor
15-
* @param {array} items
15+
* @param {array} values
1616
*/
17-
constructor(items) {
18-
super(items);
17+
constructor(values) {
18+
super(values);
1919
this._init();
2020
}
2121

@@ -24,66 +24,77 @@ class RandomRoundRobin extends RoundRobin {
2424
*/
2525
_init() {
2626
this._items = new Map();
27-
this._keys = new Set();
2827
this._round = new Set();
29-
this._initialItems.forEach((item) => this.add(item));
28+
this._initialValues.forEach((value) => this.add(value));
3029
}
3130

3231
/**
33-
* Adds an item and memoizes its key for random selection
32+
* Adds a value to the table
3433
* @public
35-
* @return {object}
34+
* @return {any} value
3635
*/
37-
add(item) {
36+
add(value) {
3837
const key = this._currentkey;
39-
this._items.set(key, { key, value: item });
40-
this._keys.add(key);
38+
this._items.set(key, { key, value });
4139
this._currentkey++;
4240
return this._items.get(key);
4341
}
4442

4543
/**
46-
* Deletes an item with its key from the table
44+
* Deletes an item by its key from the table
4745
* @public
4846
* @param {number} key
4947
* @return {boolean}
5048
*/
51-
delete(key) {
52-
if (!this._keys.has(key)) {
49+
deleteByKey(key) {
50+
if (!this._items.has(key)) {
5351
return false;
5452
}
5553

5654
if (this._currentTurn && this._currentTurn.key === key) {
57-
this._currentTurn = this._selectNextItem();
58-
if (this._currentTurn === null) {
59-
this._completedRounds += 1;
60-
}
55+
this._currentTurn = this._nextTurn();
6156
}
6257

63-
this._keys.delete(key);
6458
this._round.delete(key);
65-
6659
return this._items.delete(key);
6760
}
6861

62+
/**
63+
* Deletes items that their values match a criteria
64+
* @public
65+
* @param {function} cb
66+
* @return {number}
67+
*/
68+
deleteByValue(cb) {
69+
let deleted = 0;
70+
this._items.forEach(({ key, value }) => {
71+
if (cb(value)) {
72+
this.deleteByKey(key);
73+
deleted += 1;
74+
}
75+
});
76+
return deleted;
77+
}
78+
6979
/**
7080
* Selects the next item's key from the round
7181
* @public
7282
* @return {object}
7383
*/
74-
_selectNextItem() {
84+
_nextTurn() {
7585
if (this._currentTurn === null) {
76-
this._round = new Set(this._keys);
86+
const keys = Array.from(this._items.keys());
87+
this._round = new Set(keys);
7788
}
7889

79-
const keys = Array.from(this._round);
80-
if (keys.length === 0) {
90+
if (this._round.size === 0) {
8191
return null;
8292
}
8393

84-
const randomKey = keys[Math.floor(Math.random() * keys.length)];
85-
this._round.delete(randomKey);
86-
return this._items.get(randomKey);
94+
const roundKeys = Array.from(this._round);
95+
const selectedKey = roundKeys[Math.floor(Math.random() * roundKeys.length)];
96+
this._round.delete(selectedKey);
97+
return this._items.get(selectedKey);
8798
}
8899

89100
/**
@@ -97,15 +108,11 @@ class RandomRoundRobin extends RoundRobin {
97108
}
98109

99110
if (this._currentTurn === null) {
100-
this._currentTurn = this._selectNextItem();
111+
this._currentTurn = this._nextTurn();
101112
}
102113

103114
const item = this._currentTurn;
104-
this._currentTurn = this._selectNextItem();
105-
if (this._currentTurn === null) {
106-
this._completedRounds += 1;
107-
}
108-
115+
this._currentTurn = this._nextTurn();
109116
return item;
110117
}
111118

src/RoundRobin.d.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ export interface RoundRobinItem<T> {
44
}
55

66
export class RoundRobin<T> {
7-
constructor(items?: T[]);
8-
add(item: T): RoundRobinItem<T>;
9-
delete(key: number): boolean;
7+
constructor(values?: T[]);
8+
add(value: T): RoundRobinItem<T>;
9+
deleteByKey(key: number): boolean;
10+
deleteByValue(cb: (value: T) => boolean): number;
1011
next(): RoundRobinItem<T>;
1112
count(): number;
1213
completedRounds(): number;

src/RoundRobin.js

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,25 @@
1212
class RoundRobin {
1313
/**
1414
* @constructor
15-
* @param {array} items
15+
* @param {array} values
1616
*/
17-
constructor(items = []) {
18-
if (items && !Array.isArray(items)) {
19-
throw new Error('items must be an array');
17+
constructor(values = []) {
18+
if (values && !Array.isArray(values)) {
19+
throw new Error('RoundRobin constructor: values must be an array');
2020
}
21-
this._initialItems = items;
21+
22+
this._initialValues = values;
2223
this._currentkey = 0;
23-
this._completedRounds = 0;
2424
this._currentTurn = null;
2525
}
2626

27-
/**
28-
* Returns number of completed round of turns
29-
* @public
30-
* @return {number}
31-
*/
32-
completedRounds() {
33-
return this._completedRounds;
34-
}
35-
3627
/**
3728
* Clears the table
3829
* @public
3930
* @return {RoundRobin}
4031
*/
4132
clear() {
4233
this._currentkey = 0;
43-
this._completedRounds = 0;
4434
this._currentTurn = null;
4535
return this;
4636
}

0 commit comments

Comments
 (0)