Skip to content

Instantly share code, notes, and snippets.

@samba
Created June 28, 2012 03:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samba/3008769 to your computer and use it in GitHub Desktop.
Save samba/3008769 to your computer and use it in GitHub Desktop.
Simple set handling for Javascript, with "in" operator
/* Set theory implementation, woot!
* (c) Sam Briesemeister, 2012
*
*
* Uses Javascript objects' properties as a shortcut for determining set content.
*
* Elements must be string-like or numeric.
*
* Usage:
*
* var myset = new Set(1, 2, 3);
*
* if(3 in myset){
* alert('yay!');
* }
*
*/
(function(_global, undefined){
function arr(args){
var i = args.length, res = new Array(i);
while(i--) res[i] = args[i];
return res;
}
/** @constructor */
function Set(){
var elements = arguments, i = elements.length, k;
while(i--){
if(elements[i] instanceof Set){
for(k in elements[i]){
if(Set.has(elements[i], k)) this[k] = elements[i][k];
}
} else if(elements[i] && elements[i].pop){
k = elements[i].length;
while(k--) this[elements[i][k]] = null;
}
else this[elements[i]] = null;
}
}
Set.add = function(_set, element, value){
_set[element] = value || null;
};
Set.has = function(_set, element){
return Object.prototype.hasOwnProperty.call(_set, element) && _set[element] !== undefined;
};
Set.remove = function(_set, element){
_set[element] = undefined;
delete _set[element];
};
Set.count = function(_set){
var count = 0;
for(var i in _set){
if(Set.has(_set, i)) count++;
}
return count;
};
// Create sets intelligently
Set.create = function(){
if(arguments.length == 1 && arguments[0] instanceof Set) return arguments[0];
return new Set(arr(arguments));
};
// Find the intersection of multiple sets
Set.intersect = function(){
var i, j, k, result = new Set(arguments[0]); // initial
for(i = 1; i < arguments.length; i++){
k = new Set(arguments[i]);
for(j in result){
if(Set.has(result, j) && !Set.has(k, j)) Set.remove(result, j);
}
}
return result;
};
// Find the union of multiple sets
Set.union = function(){
var i, j, k, result = Set.create(arguments[0]); // initial
for(i = 1; i < arguments.length; i++){
k = Set.create(arguments[i]);
for(j in k){
if(Set.has(k, j)) Set.add(result, j, k[j]);
}
}
return result;
};
Set.subtract = function(one, two){
var result = new Set(one);
for(var i in two){
if(Set.has(two, i)) Set.remove(result, i);
}
return result;
};
_global.setmagic = _global.Set = Set;
})(window);
// Test
var x = new setmagic([ 1, 2, 3, 4 ]);
var y = new setmagic([ 3, 4, 5, 6 ]);
console.log('intersect', setmagic.intersect(x, y));
console.log('union', setmagic.union(x, y));
console.log('subtract', setmagic.subtract(x, y));
console.log('3 in intersect', 3 in setmagic.intersect(x, y)); // true
console.log('2 in intersect', 2 in setmagic.intersect(x, y)); // false
var core_size = 5000, rand_size = 100, core_set = [], x2, y2, curval = 0;
console.time('scale test setup');
for(var i = 0; i < core_size; i++){
core_set.push(curval++);
}
console.time('scale test: create core');
core_set = new setmagic(core_set);
console.timeEnd('scale test: create core');
console.log('set size core: ', Set.count(core_set));
x2 = new setmagic(core_set);
y2 = new setmagic(core_set);
for(var i = 0; i < rand_size; i++){
setmagic.add(x2, curval++);
setmagic.add(y2, curval++);
}
console.time('scale test setup');
console.log('set size x2:', Set.count(x2));
console.log('set size y2:', Set.count(y2));
console.time('scale test: intersection');
var res = setmagic.intersect(x2, y2);
console.timeEnd('scale test: intersection');
console.log('rand intersect', Set.count(res), res);
console.time('scale test: search');
console.log('200 in core', (200 in core_set));
console.timeEnd('scale test: search');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment