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)

7

7 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.

3

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 
8

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] 
4

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; 
6

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); }; }; 
4

Map 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) 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy