22

Is there any way to create Set data structure(Unique Collections) like java in javascript?

    5 Answers 5

    45

    For a set of strings, I would just use a object with the value true.

    var obj = {}; obj["foo"] = true; obj["bar"] = true; if(obj["foo"]) { // foo in set } 

    This is basically how HashSet works in Java, assuming the JavaScript object is implemented as a hashtable (which is typical).

    4
    • So how to remove an object from that set? obj["foo"]=null? or obj["foo"]=false?CommentedApr 5, 2011 at 13:47
    • 8
      @Eran, delete obj["foo"] or delete obj.foo.CommentedApr 5, 2011 at 13:53
    • Thanks for teaching an old dog a new trick :) this is amazing I never encountered it in JS, brings me back to my C++ days though...CommentedApr 5, 2011 at 16:18
    • @Eran, yeah. As you probably know, it's quite different in JavaScript, given that it's garbage-collected and there are no destructors.CommentedApr 5, 2011 at 19:23
    9

    I have written a JavaScript implementation of a hash set that is similar to Java's HashSet. It allows any object (not just strings) to be used as a set member. It's based on the keys of a hash table.

    http://code.google.com/p/jshashtable/downloads/list

    Documentation will follow shortly, I promise. For now, the source should give you the API pretty clearly, and here's an example:

    var s = new HashSet(); var o1 = {name: "One"}, o2 = {name: "Two"}; s.add(o1); s.add(o2); s.add(o2); s.values(); // Array containing o1 and a single reference to o2 
      1

      Well though it seemed to be a common problem, and I found what seemed to be a good Set class on the net that supports objects, I wanted a simpler one and ended up writing one myself... in case anyone else finds it useful...

      /** * A Javascript Class that represents a set of unique values * * Usage: * * var s = new jsSet(); * * s.add('a1'); s.add('a2'); * * s.list(); >> ['a1','a2'] * * s.remove('a1'); s.list(); >> ['a2'] * * s.contains('a1') >> false * * s.contains('a2') >> true * * can be chained * s.add(null).add('hello'); * * add array * s.addAll([ null, 'a', 'b' ]); * * remove array * s.addAll([ null, 'a', 'b' ]); * * retrieve the elements as a list * s.list(); * * size of the set * s.size(); * */ function jsSet() { // null can also be an element of the set, but needs // a separate indication to differentiate it from // the string "null" as well this.isNullAdded = false; // private member variable hence no 'this' var map = {}; // Scope for optimization // could be cached instead of generating each time // this.uniqueList = []; // returns true if the element is in this set, false otherwise this.contains = function(key) { if (key === null) return this.isNullAdded; else if (key === undefined) return false; else return map[key] ? true : false; }; // adds the element to the set this.add = function(val) { if (val === null) this.isNullAdded = true; else if (val !== undefined) map[val] = true; return this; }; // adds all the elements of the array to the set this.addAll = function(val) { if (val !== null && val !== undefined && val instanceof Array) { for ( var idx = 0; idx < val.length; idx++) { this.add(val[idx]); } } return this; }; // removes the specified element from the set this.remove = function(val) { if (val === null) this.isNullAdded = false; else if (val !== undefined) delete map[val]; return this; }; // removes all the element in the array from the set this.removeAll = function(val) { if (val !== null && val !== undefined && val instanceof Array) { for ( var idx = 0; idx < val.length; idx++) { console.log('val: %s:%s', idx, val[idx]); this.remove(val[idx]); } } return this; }; // empties the set of all values this.clear = function() { this.isNullAdded = false; map = {}; return this; }; // returns the number of elements in the set this.size = function() { return this.list().length; }; // returns true if the set is empty, false otherwise this.isEmpty = function() { return this.list().length > 0? false: true; }; // returns the elements of the set as a list this.list = function() { var arr = []; if (this.isNullAdded) arr.push(null); for (o in map) { // protect from inherited properties such as // Object.prototype.test = 'inherited property'; if (map.hasOwnProperty(o)) arr.push(o); } return arr; }; }; 
      1
      • if we don't need null values in the Set, then we can just do a remove(null) after adding all elements.
        – msanjay
        CommentedNov 4, 2011 at 11:40
      0

      In modern browsers, I would use a Map using only the keys' methods. For example:

      • New set: let mySet = new Map();
      • Add element: mySet.set(element, 1)
      • Remove element: mySet.delete(element)
      • Contains element: mySet.has(element)

      You can make your own wrapper if you don't want to see the Map implementation. This approach is how Java HashSet is implemented, it uses a HashMap and only uses the key methods.

        0

        Javascript now provides (part of es6) Set Api, which can be used to create unique collection.

        var set = new Set([1,1,2,3]); set.add(1); set.add(4); 

        For more info, visit - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

          Start asking to get answers

          Find the answer to your question by asking.

          Ask question

          Explore related questions

          See similar questions with these tags.