DEV Community

Zac Anger
Zac Anger

Posted on

4

What is Set?

Originally posted on my blog.

Someone recently asked in a Slack channel how they might clean up the following code:

getNames (contacts) {
  let contacts_set = []

  contacts.forEach((contact) => {
    let firstName = get(contact, 'contactInfo.firstName')
    let lastName = get(contact, 'contactInfo.lastName')
    let fullName = `${firstName} ${lastName}`

    if (contacts_set.includes(fullName)) {
      return
    } else {
      contacts_set.push(fullName)
    }

    set(this, 'contactsSet', contactsSet)
  })
}
Enter fullscreen mode Exit fullscreen mode

(Note that the get and set going on here seemed to be Ember-specific, or a _.get type of thing. I don't know Ember, so I'm not positive.)

And I said, how about this?

getNames: (contacts) =>
  [...new Set(
    contacts.map(({ contactInfo: { firstName, lastName }}) =>
      `${firstName} ${lastName}`))]
Enter fullscreen mode Exit fullscreen mode

I like this version because it's concise, readable (to me, at least?), mutation-free, and declarative.

And then someone else asked:

Can some one eli5 what Set is that's referenced above?

Which made me realise that a lot of folks still aren't using a lot of the nice new things from ES2015, so I explained a bit. Here's how I understand it.

Set is a new (in ES2015) iterable builtin (like Array, String, TypedArray). Map is also new in 2015. Set is to Array as Map is to Object, kinda.

For practical usage Set is basically Array but unique, and with different methods. add, has, delete, size, and some others. There's a lot more info on MDN.

You can pass Set an iterable, which is why the thing I have above works (because the contacts.map... thing inside new Set() results in an array).

In that case Set isn't being used for too much besides just the fact that it's Set (so it only holds unique values). Someone else pointed out in the same channel that maybe it's not the best idea if you have a very large collection, because then you're creating a whole extra collection in the process, which is totally true.

There's a bit more background here on what JS's Set is supposed to be kind of like.

And underneath it sorta looks like this:

class Set {
  constructor () {
    this.storage = []
  }
  add (a) {
    if (!this.storage.includes(a)) {
      this.storage.push(a)
    }
  }
  has (a) {
    return this.storage.includes(a)
  }
  remove (a) {
    this.storage.splice(this.storage.indexOf(a), 1)
  }
}
Enter fullscreen mode Exit fullscreen mode

That's a lot of stuff, but mostly you can think of Set as a thing that's like Array but it only holds unique things.

There's also a WeakSet which can only hold objects. I haven't really found a valid use case for WeakSet and WeakMap yet, personally.

Set turns out to be pretty useful. Definitely play around with it!

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more