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)
77 Answers
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.
3Under 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 8Use 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] 4You 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; 6I'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); }; }; 4Map or if no need to iterate WeakMap
let m1=new Map(); m1.set('isClosed',false); m1.set('isInitialized',false); m1.set('isClosed',true); m1.forEach(function(v,k) { console.log(`${k}=${v}`); });Only Map in Javascript has faster look ups . if you want only for look ups you can create a lookup map out of the array you have like the below and use it
function createLookUpMap(arr = []) { return new Map(arr.map(item => [item, true])); } const lookupMap = createLookUpMap(['apple', 'orange', 'banana']); lookupMap.has('banana'); // O(1)