What is the JavaScript equivalent to a C# HashSet?
I have a list of a few thousand integer keys. The only thing I need to do with this list is say whether or not a given value is in the list.
For C# I would use a HashSet
to make that look-up fast. What's the JavaScript equivalent?
Minimal support level: IE 9+, jQuery (current)
Actually JavaScript provides a Set object, fairly simple to use:
var set = new Set();
set.add(1);
set.add(2);
set.has(1) // true
Unfortunately, it is not compatible with IE9.
Under the hood, the JavaScript Object is implemented with a hash table.
So, your Key:Value
pair would be (your integer):true
A constant-time lookup function could be implemented as:
var hash = {
1:true,
2:true,
7:true
//etc...
};
var checkValue = function(value){
return hash[value] === true;
};
checkValue(7); // => true
checkValue(3); // => false
Use an object. To add a key to the set, do:
object[key] = true;
To test whether a key is in the set, do:
if (object.hasOwnProperty(key)) { ... }
To remove a key from the set, do:
delete object[key]
You can use just a regular JavaScript object and the 'in' keyword to see if that object has a certain key.
var myObj = {
name: true,
age: true
}
'name' in myObj //returns true;
'height' in myObj // returns false;
Or if you know you're going to have keys in your object that might be built in JavaScript object properties use...
var myObj = {
name: true,
age: true
}
myObj.hasOwnProperty('name') //returns true;
myObj.hasOwnProperty('height') // returns false;
I've read the solutions and I tried some. After trying to use the object[key]
method I realized that it wasn't going to work. I wanted a HashSet that could store HTML elements. When adding these objects the key
was translated to a string, so I came up with my own set based on jQuery. It supports add
, remove
, contains
and clear
.
var HashSet = function () {
var set = [];
this.add = function (obj) {
if (!this.contains(obj)) {
set.push(obj);
}
};
this.remove = function (obj) {
set = jQuery.grep(set, function (value) {
return value !== obj;
});
};
this.clear = function () {
set = [];
};
this.contains = function (obj) {
return $.inArray(obj, set) > -1;
};
this.isEmpty = function () {
return set.length === 0;
};
};
Note
When adding something like $('#myElement')
to the set, one should add the real HTML element $('#myElement')[0]
. Oh... and if you want to keep a list of changed controls - use the name of the element (gave me a problem with :radio
controls).
Note2
I think the object[key]
might be faster for your integers.
Note3
If you are only going to store numbers or string, this set will be faster:
var HashSet = function () {
var set = {};
this.add = function (key) {
set[key] = true;
};
this.remove = function (key) {
delete set[key];
};
this.clear = function () {
set = {};
};
this.contains = function (key) {
return set.hasOwnProperty(key);
};
this.isEmpty = function () {
return jQuery.isEmptyObject(set);
};
};