I'm looking for a decent implementation of a set data structure in JavaScript. It should be able to support elements that are plain JavaScript objects.

So far I only found Closure Library's structs.Set, but I don't like the fact that it modifies my data.

You could build a simple wrapper around the keys of a hash table provided by my jshashtable. I have one knocking around somewhere that I will dig out later.

**UPDATE**

I have completed and tested an implementation of HashSet and uploaded it to the jshashtable project on GitHub. You can download it or view the source.

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

**ECMAScript 6 has it**

Spec: http://www.ecma-international.org/ecma-262/6.0/#sec-set-constructor

Usage: https://github.com/lukehoban/es6features#map--set--weakmap--weakset

Example:

```
var s = new Set()
s.add("hello").add("goodbye").add("hello")
s.size === 2
s.has("hello") === true
```

A module that implements it for browsers without support: https://github.com/medikoo/es6-set

I don't think there's a way to work with object's hash code other than store it in the object itself. Strictly speaking, it's possible to create a set class without hashing, using simple linear search, but this would hardly be efficient.

Use the ECMAScript 2015 (ES6) standard Set Data structure really easy to use:

```
var mySet = new Set();
mySet.add(1);
mySet.add(5);
mySet.add("some text");
var o = {a: 1, b: 2};
mySet.add(o);
mySet.has(1); // true
mySet.has(3); // false, 3 has not been added to the set
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has("Some Text".toLowerCase()); // true
mySet.has(o); // true
mySet.size; // 4
mySet.delete(5); // removes 5 from the set
mySet.has(5); // false, 5 has been removed
mySet.size; // 3, we just removed one value
```

Be aware that sets don't work with `ng-repeat`

. So it is better you use an array and just apply a unique filter

I like Simple-JS-Set (probably because I wrote it). It supports any sort of JavaScript object. It has the following API:

`Set(hashFunction)`

: (Constructor) Instantiate a new set with the given`hashFunction`

(defaults to`JSON.stringify`

)`add(item)`

: Add an item to the set`remove(item)`

: Remove an item from the set`contains(item)`

: Return whether or not the item is contained in the set`size()`

: Return the number of unique items in the set`each(function(item), thisObj)`

: Execute a function with each item in the set in context of`thisObj`

In ES6 version of Javascript you have built in type for set (check compatibility with your browser).

```
var numbers = new Set([1, 2, 4]); // Set {1, 2, 4}
```

To **add an element** to the set you simply use `.add()`

, which runs in `O(1)`

and either adds the element to set (if it does not exist) or does nothing if it is already there. You can add element of any type there (arrays, strings, numbers)

```
numbers.add(4); // Set {1, 2, 4}
numbers.add(6); // Set {1, 2, 4, 6}
```

To **check the number of elements** in the set, you can simply use `.size`

. Also runs in `O(1)`

```
numbers.size; // 4
```

To **remove the element from the set** use `.delete()`

. It returns true if the value was there (and was removed), and false if the value did not exist. Also runs in `O(1)`

.

```
numbers.delete(2); // true
numbers.delete(2); // false
```

To **check whether the element exist** in a set use `.has()`

, which returns true if the element is in the set and false otherwise. Also runs in `O(1)`

.

```
numbers.has(3); // false
numbers.has(1); // true
```

In addition to methods you wanted, there are few additional one:

`numbers.clear();`

would just remove all elements from the set`numbers.forEach(callback);`

iterating through the values of the set in insertion order`numbers.entries();`

create an iterator of all the values`numbers.keys();`

returns the keys of the set which is the same as`numbers.values()`

There is also a Weakset which allows to add only object-type values.

©2020 All rights reserved.