Skip to content

Commit

Permalink
allow features to have numeric ids
Browse files Browse the repository at this point in the history
  • Loading branch information
mcwhittemore committed Apr 27, 2018
1 parent 85f39bf commit dc675c0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
31 changes: 24 additions & 7 deletions src/lib/string_set.js
@@ -1,37 +1,54 @@
function StringSet(items) {
this._items = {};
this._nums = {};
this._length = items ? items.length : 0;
if (!items) return;
for (let i = 0, l = items.length; i < l; i++) {
this.add(items[i]);
if (items[i] === undefined) continue;
this._items[items[i]] = i;
if (typeof items[i] === 'string') this._items[items[i]] = i;
else this._nums[items[i]] = i;

}
}

StringSet.prototype.add = function(x) {
this._length = this._items[x] ? this._length : this._length + 1;
this._items[x] = this._items[x] ? this._items[x] : this._length;
if (this.has(x)) return this;
this._length++;
if (typeof x === 'string') this._items[x] = this._length;
else this._nums[x] = this._length;
return this;
};

StringSet.prototype.delete = function(x) {
this._length = this._items[x] ? this._length - 1 : this._length;
if (this.has(x) === false) return this;
this._length--;
delete this._items[x];
delete this._nums[x];
return this;
};

StringSet.prototype.has = function(x) {
return this._items[x] !== undefined;
if (typeof x !== 'string' && typeof x !== 'number') return false;
return this._items[x] !== undefined || this._nums[x] !== undefined;
};

StringSet.prototype.values = function() {
const orderedKeys = Object.keys(this._items).sort((a, b) => this._items[a] - this._items[b]);
return orderedKeys;
const values = [];
Object.keys(this._items).forEach(k => {
values.push({ k: k, v: this._items[k] });
});
Object.keys(this._nums).forEach(k => {
values.push({ k: JSON.parse(k), v: this._nums[k] });
});

return values.sort((a, b) => a.v - b.v).map(a => a.k);
};

StringSet.prototype.clear = function() {
this._length = 0;
this._items = {};
this._nums = {};
return this;
};

Expand Down
22 changes: 14 additions & 8 deletions test/string_set.test.js
Expand Up @@ -13,8 +13,8 @@ test('StringSet constructor and API', t => {
t.equal(typeof StringSet.prototype.clear, 'function', 'exposes set.clear');
t.equal(Object.keys(StringSet.prototype).filter(k => k[0] !== '_').length, 5, 'no unexpected methods');

const populatedSet = new StringSet(['a', 'b']);
t.deepEqual(populatedSet.values(), ['a', 'b'], 'populated by constructor arg');
const populatedSet = new StringSet(['a', 4, 'b']);
t.deepEqual(populatedSet.values(), ['a', 4, 'b'], 'populated by constructor arg');

t.end();
});
Expand All @@ -28,29 +28,35 @@ test('StringSet#add', t => {
t.deepEqual(set.values(), ['a', 'b']);
set.add('a');
t.deepEqual(set.values(), ['a', 'b']);
set.add(3);
t.deepEqual(set.values(), ['a', 'b', 3]);
t.end();
});

test('StringSet#delete', t => {
const subject = ['a', 'b'];
const subject = ['a', 'b', 2];
const set = new StringSet(subject);
set.delete('a');
t.deepEqual(set.values(), ['b']);
t.deepEqual(set.values(), ['b', 2]);
set.delete('a');
t.deepEqual(set.values(), ['b']);
t.deepEqual(set.values(), ['b', 2]);
set.delete();
t.deepEqual(set.values(), ['b']);
t.deepEqual(set.values(), ['b', 2]);
set.delete('b');
t.deepEqual(set.values(), [2]);
set.delete(2);
t.deepEqual(set.values(), []);
t.deepEqual(subject, ['a', 'b'], 'source array not mutated');
t.deepEqual(subject, ['a', 'b', 2], 'source array not mutated');
t.end();
});

test('StringSet#has', t => {
const set = new StringSet(['a', 'b']);
const set = new StringSet(['a', 'b', 2]);
t.equal(set.has('a'), true);
t.equal(set.has('b'), true);
t.equal(set.has(2), true);
t.equal(set.has('c'), false);
t.equal(set.has(4), false);
t.end();
});

Expand Down

0 comments on commit dc675c0

Please sign in to comment.