DEV Community

Sets in ES6 - A Quick Guide

Ben Mildren on January 18, 2017

Overview Sets are a new data type in ES6. They're similar to Arrays with one major difference, each value must be unique. They have an API that...
Collapse
 
misterwhat profile image
Jonas Winzen • Edited

The third value is the current Set you're iterating over. A number of methods have this argument, and I've never figured out why

This allows you to reuse the callback in several places, without losing the flexibility you have, when defining the callback inline. From a callback that is defined somewhere else, you will loose the ability to look at the object you are currently working.
Use case: transform an array of values to an srray of strings, that have the form `${value} of ${array.length} items`.
Without the third parameter, you'd need to write a higher order function that takes the length (or the array itself) returns a function that can be used as a callback function:

const createCallback = array => (index, value) => (
value + " of " + array.length + " items"
);
const inputArray = ["foo", "bar"];
console.log(inputArray.map(createCallback(inputArray)));

Code like this is something what I call an "eyebrow raiser". What happens if someone changes the createCallback function and mutates the array there (think of the poor guy, who has to debug that... )? You need to take care to have tests in place that protect the code from this kind of change (super edgy edge case that is super dangerous at the same time).

Collapse
 
antjanus profile image
Antonin J. (they/them) • Edited

More than that! You need it if you chain methods like so:

myArr
  .filter(val => !!val)
  .forEach((val, idx, filteredArr) => {
    // now has access to the filtered array via `filteredArr`
  })
  .map((val, idx, filteredArr) => {

  })
  .forEach((val, idx, mappedArr) => {
    // now has access to the filtered and mapped array via `mappedArr`
  });

Otherwise, you'd have to execute and assign these to variables and reach out of the inner scope of the call back function.

Collapse
 
realdolos profile image
Dolores Greatamsky • Edited

Some minor corrections:

  • You wrote foo.add(key, value) instead of foo.add(key) in your API overview.
  • You wrote "Sets do not have keys so they do not have a .keys()". Actually they do; it's just an alias for .values(). This is so that they provide the same iteration API functions as Maps, which can be useful when writing certain algorithms which will operate on container keys and/or values. Same reason Sets have .entries(). The important difference being that @@iterator maps to Map.entries() but Set.values().