344

MDN references JavaScript's Set collection abstraction. I've got an array of objects that I'd like to convert to a set so that I am able to remove (.delete()) various elements by name:

var array = [
    {name: "malcom", dogType: "four-legged"},
    {name: "peabody", dogType: "three-legged"},
    {name: "pablo", dogType: "two-legged"}
];

How do I convert this array to a set? More specifically, is it possible to do this without iterating over the above array? The documentation is relatively lacking (sufficient for instantiated sets; not for conversions - if possible).

I may also be thinking of the conversion to a Map, for removal by key. What I am trying to accomplish is an iterable collection that can be accessed or modified via accessing the elements primarily via a key (as opposed to index).

Conversion from an array to the other being the ultimate goal.

24
  • 2
    sounds like a plain old Object will work for you... Commented Mar 10, 2015 at 13:32
  • 3
    @Thomas: so I am missing something, which I want to learn. What is the difference between var s = new Set(), adding objects and issuing s.delete(whatever) - and var o = {1: 'aaa', 2: 'bbbb' ... } and issuing delete(o['1']) ? Commented Mar 10, 2015 at 13:39
  • 1
    @Veverke that was more descriptive than you initial comment (+1). Thank you. But, again, is it possible to do that without iterating over the array for addition of the contents of the array to the object and to retain a list like, key-accessible structure? Sounds like you've got an idea. I wouldn't mind seeing it in an answer format if you've got the time to elaborate. Commented Mar 10, 2015 at 13:41
  • 2
    That array object isn't legal, since {"bob", "dole"} isn't a valid object. Commented Mar 10, 2015 at 13:51
  • 1
    @Veverke ES6 Set and Map are "pure" implementation of those data constructs that don't suffer the issues that an Object can when things are added to its prototype. Commented Mar 10, 2015 at 13:54

6 Answers 6

500

Just pass the array to the Set constructor. The Set constructor accepts an iterable parameter. The Array object implements the iterable protocol, so its a valid parameter.

var arr = [55, 44, 65];
var set = new Set(arr);
console.log(set.size === arr.length);
console.log(set.has(65));

See here

Sign up to request clarification or add additional context in comments.

2 Comments

strictly correct, although I've hesitated to add an answer myself since the OP's data is malformed and it's therefore unclear exactly what he expects
This does not work on IE11. It does not support this constructor. I would avoid it unless you know which browsers your users are going to use.
66

If you start out with:

let array = [
    {name: "malcom", dogType: "four-legged"},
    {name: "peabody", dogType: "three-legged"},
    {name: "pablo", dogType: "two-legged"}
];

And you want a set of, say, names, you would do:

let namesSet = new Set(array.map(item => item.name));

Comments

17
const categoryWithDuplicates =[
  'breakfast', 'lunch',
  'shakes',    'breakfast',
  'lunch',     'shakes',
  'breakfast', 'lunch',
  'shakes'
]

const categoryWithoutDuplicates =[...new Set(categoryWithDuplicates)];
console.log(categoryWithoutDuplicates)

Output: [ 'breakfast', 'lunch', 'shakes' ]

Comments

13

By definition "A Set is a collection of values, where each value may occur only once." So, if your array has repeated values then only one value among the repeated values will be added to your Set.

var arr = [1, 2, 3];
var set = new Set(arr);
console.log(set); // {1,2,3}


var arr = [1, 2, 1];
var set = new Set(arr);
console.log(set); // {1,2}

So, do not convert to set if you have repeated values in your array.

1 Comment

What if the whole idea is to de-duplicate the array, and then use set operators on the resulting set?
3

What levi said about passing it into the constructor is correct, but you could also use an object.

I think what Veverke is trying to say is that you could easily use the delete keyword on an object to achieve the same effect.

I think you're confused by the terminology; properties are components of the object that you can use as named indices (if you want to think of it that way).

Try something like this:

var obj = {
    "bob": "dole",
    "mr.": "peabody",
    "darkwing": "duck"
};

Then, you could just do this:

delete obj["bob"];

The structure of the object would then be this:

{
    "mr.": "peabody",
    "darkwing": "duck"
}

Which has the same effect.

7 Comments

Thanks Astro :-). Indeed, this opened up the question: "what is the difference between a Set object and a plain object" ? Although, as I have noted in the comments above, "Set" is a wrap up type that offers the "nice to have functionality" of "clear".
In a short, I think the post's title should be changed to "What is the difference between a Set object and a plain object in javascript", and note that "In trying to achieve this this and that... I ended up asking myself what is the difference between...
@Veverke "what is the difference between a Set object and a plain object", could just read the doc ..
@Hacketo: do you find any other than Set providing "Clear" in its api ?
@Veverke size maybe; a plain object can have multiple same value, Set can't... just as the doc says
|
0
var yourSetAsArray = Array.from(new Set([1, 2, 2, 3, 3, 4, 4])); 
// returns [1, 2, 3, 4]

2 Comments

Please read How do I write a good answer?. While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others.
this is what I look for, thumb up!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.