Javascript Data Structure Tutorial - Javascript Set








A set is a collection of unique elements.

The elements of a set are called members.

The members of a set are unordered and that no member can occur in a set more than once.

A set containing no members is called the empty set.

Two sets are considered equal if they contain exactly the same members.

A set is considered a subset of another set if all the members of the first set are contained in the second set.

Set Operations

The fundamental operations performed on sets are:

  • Union - A new set is created by combining the members of one set with the members of another set.
  • Intersection - A new set is created by adding all the members of one set that also exist in a second set.
  • Difference - A new set is created by adding all the members of one set except those that also exist in a second set.




The Set Class Implementation

The Set class implementation is built around an array.


function Set() { /*from  w  w w .  java2  s.c  o  m*/
    this.dataStore = []; 
    this.add = add; 
    this.remove = remove; 
    this.size = size; 
    this.union = union; 
    this.intersect = intersect; 
    this.subset = subset; 
    this.difference = difference; 
    this.show = show; 
    this.contains = contains;
    this.union = union;
    this.intersect = intersect;
    this.subset = subset;
    this.size = size;
    this.difference = difference;
} 
function add(data) { 
    if (this.dataStore.indexOf(data) < 0) { 
        this.dataStore.push(data); 
        return true; 
    } else { 
        return false; 
    } 
} 
function remove(data) { 
    var pos = this.dataStore.indexOf(data); 
    if (pos > -1) { 
        this.dataStore.splice(pos,1); 
        return true; 
    } else { 
        return false; 
    } 
} 
function show() { 
    return this.dataStore; 
} 
function contains(data) { 
    if (this.dataStore.indexOf(data) > -1) { 
        return true; 
    } else { 
        return false; 
    } 
} 
function union(set) { 
    var tempSet = new Set(); 
    for (var i = 0; i < this.dataStore.length; ++i) { 
        tempSet.add(this.dataStore[i]); 
    } 
    for (var i = 0; i < set.dataStore.length; ++i) { 
        if (!tempSet.contains(set.dataStore[i])) { 
            tempSet.dataStore.push(set.dataStore[i]); 
        } 
    } 
    return tempSet; 
} 
function intersect(set) { 
    var tempSet = new Set(); 
    for (var i = 0; i < this.dataStore.length; ++i) { 
        if (set.contains(this.dataStore[i])) { 
            tempSet.add(this.dataStore[i]); 
        } 
    } 
    return tempSet; 
} 

function subset(set) { 
    if (this.size() > set.size()) { 
        return false; 
    } else { 
        for (var member in this.dataStore) { 
            if (!set.contains(member)) { 
                return false; 
            } 
        } 
    } 
    return true; 
} 
function size() { 
    return this.dataStore.length; 
} 
function difference(set) { 
    var tempSet = new Set(); 
    for (var i = 0; i < this.dataStore.length; ++i) { 
        if (!set.contains(this.dataStore[i])) { 
            tempSet.add(this.dataStore[i]); 
        } 
    } 
    return tempSet; 
} 


var names = new Set(); 
names.add("D"); 
names.add("J"); 
names.add("C"); 
names.add("M"); 
names.add("R"); 
if (names.add("M")) { 
    console.log("M added") 
} else { 
    console.log("Can't add M, must already be in set"); 
} 
console.log(names.show()); 
var removed = "M"; 
if (names.remove(removed)) { 
    console.log(removed + " removed."); 
} else { 
    console.log(removed + " not removed."); 
} 
names.add("C"); 
console.log(names.show()); 
removed = "A"; 
if (names.remove(removed)) { 
    console.log(removed + " removed."); 
} else { 
    console.log(removed + " not removed."); 
} 


var cis = new Set(); 
cis.add("M"); 
cis.add("C"); 
cis.add("J"); 
cis.add("R"); 
var dmp = new Set(); 
dmp.add("R"); 
dmp.add("C"); 
dmp.add("J"); 
var it = new Set(); 
it = cis.union(dmp); 
console.log(it.show()); 

var inter = cis.intersect(dmp); 
console.log(inter.show());

var it = new Set(); 
it.add("C"); 
it.add("C"); 
it.add("J"); 
it.add("D"); 
it.add("J"); 
it.add("T"); 
it.add("R"); 
it.add("M"); 

if (dmp.subset(it)) { 
    console.log("DMP is a subset of IT."); 
} else { 
    console.log("DMP is not a subset of IT."); 
} 

var diff = new Set(); 
diff = cis.difference(it); 
console.log("[" + cis.show() + "] difference [" + it.show() + "] -> [" + diff.show() + "]"); 

The code above generates the following result.





Example 2

The following code shows how to create Set data structure with prototype.


var Set = function(){
  this._storage = {};// w  ww.ja  v  a 2  s.  c o m
};

Set.prototype.generateKey = function(value) {
  var type = typeof value;
  if (type === 'function') {
    value = value.toString();
  }
  else if (type === 'undefined') {
    return 'undefined';
  }
  //NaN
  else if (type === 'number' && !value && value !== 0) {
    return 'NaN';
  }
  else {
    value = JSON.stringify(value);
  }
  return value;
};

Set.prototype.add = function(value){
  value = this.generateKey(value);
  this._storage[value] = value;
};

Set.prototype.contains = function(value){
  value = this.generateKey(value);
  return this._storage[value] === value;
};

Set.prototype.remove = function(value){
  value = this.generateKey(value);
  var temp = this._storage[value];
  return (delete this._storage[value]) && temp;
};

var set = new Set();

set.add(1);
set.add(1);
set.add(2);
set.add(3);

console.log(set.contains(1));