Additional Set.prototype methods

# David Bruant (12 years ago)

I've been playing with Sets recently and believe that the following additions would make them more useful by default:

  • Set.prototype.map
  • Set.prototype.filter
  • Set.prototype.toJSON = function(){
       return [...this];
    };
    

The 2 first are to easily create sets from existing sets very much like what we already have with arrays. I haven't had a use for a .reduce yet, but maybe that would make sense too? The toJSON is just to provide a good default. Obviously anyone disatisfied with it can shadow it on specific instances. But this serialization makes more sense by default than the one you get now (own properties of the set object... which have none in common usages?)

Hopefully both IE11 and Firefox having shipped Sets without this toJSON behavior won't prevent this change?

# Calvin Metcalf (12 years ago)

I had the same idea a couple weeks ago and turned it into a library calvinmetcalf/set.up if anyone finds it useful.

It adds all the array methods that make sense, ie reduce but not reduceRight

# Brendan Eich (12 years ago)

David Bruant wrote:

I've been playing with Sets recently and believe that the following additions would make them more useful by default:

  • Set.prototype.map
  • Set.prototype.filter
  • Set.prototype.toJSON = function(){
       return [...this];
    };
    

The 2 first are to easily create sets from existing sets very much like what we already have with arrays.

These seem good.

I haven't had a use for a .reduce yet, but maybe that would make sense too?

Are Sets ordered just because for-of says so? :-P

When in doubt, leave it out.

The toJSON is just to provide a good default. Obviously anyone disatisfied with it can shadow it on specific instances. But this serialization makes more sense by default than the one you get now (own properties of the set object... which have none in common usages?)

Hopefully both IE11 and Firefox having shipped Sets without this toJSON behavior won't prevent this change?

No draft-spec implementation can foreclose further spec additions to a built-in prototype, in the draft spec as it evolves at any rate. Yes, Array.prototype.values bit us, but via 'with' (of course -- the one you should most suspect!). Not here, though.

# Allen Wirfs-Brock (12 years ago)

On Dec 31, 2013, at 1:53 PM, Brendan Eich wrote:

Are Sets ordered just because for-of says so? :-P

Actually, according to the spec. they are ordered, but this is only currently observable via for-of. For-or was the motivation specifying an order, but other operations could make use of that ordering.

# Rick Waldron (12 years ago)

On Tue, Dec 31, 2013 at 5:30 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

Actually, according to the spec. they are ordered, but this is only currently observable via for-of.

And the existing .forEach, right?

# Mark S. Miller (12 years ago)

Sets and Maps are deterministically ordered by insertion order.

# Allen Wirfs-Brock (12 years ago)

On Dec 31, 2013, at 2:38 PM, Rick Waldron wrote:

And the existing .forEach, right?

right

# Brandon Benvie (12 years ago)

How about Maps? And since their order is deterministic, how about the rest of the array extras?

# Forrest L Norvell (12 years ago)

On Tue, Dec 31, 2013 at 2:45 PM, Mark S. Miller <erights at google.com> wrote:

Sets and Maps are deterministically ordered by insertion order.

I understand how the need to specify a deterministic traversal order for for-of led to this result, but doesn't that preclude a number of (potentially faster with larger collections) implementation strategies, like using hashing under the hood?

# Mark Miller (12 years ago)
# David Bruant (12 years ago)

Le 01/01/2014 00:34, Brandon Benvie a écrit :

How about Maps?

Sets and arrays are very much alike in that they are collections of items. Maps are more like objects. I'd expect maps to have methods like the one we apply on object (Object.keys, etc.), but I think everything is covered. I guess a default toJSON could help Maps too.

And since their order is deterministic, how about the rest of the array extras?

I don't have a strong opinion either way. I've noticed I wanted the one I listed, but felt like being conservative for a first shot of suggestions.

I feel there might be room for some static methods too like Set.union and Set.intersection. These are annoying with arrays (while keeping uniqueness of elements)

# David Bruant (12 years ago)

Le 31/12/2013 20:52, Calvin Metcalf a écrit :

I had the same idea a couple weeks ago and turned it into a library calvinmetcalf/set.up if anyone finds it useful.

hmm... It is useful, but not future-proof. If methods with these names ever get standardized, your code will override them. If other code wants to use the standard one and there is the least semantic deviation between your library and the standard, this other code will break in subtle ways.

I'd recommand prefixing every non-standard addition with _ as in:

 Set.prototype._filter = function(func, context){
     ...
 }

This way, if a standard filter method arrives, your code will use _filter, other code will use the standard filter unambiguously and no code will break. This additional _ guarantees non-collision with future standard methods. I suggested this some time ago and no browser vendor nor standard folks complained too hard for this not to work, so I guess it can be declared author territory. The flag is up. Note: this _ prefixing trick can also work for Array.prototype and String.prototype and EventTarget.prototype.

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

Sets and Maps are deterministically ordered by insertion order.

I know; my point was whether this should be reduce order (and reduceRight the reverse?).

# Ryan Scheel (12 years ago)

I'd like to add find(predicate(element, set)) to the list of methods that would be useful.

# Rick Waldron (12 years ago)

+1

Considering Array.prototype gained a find() method, this is an obvious addition to Set.

# Tab Atkins Jr. (12 years ago)

I agree with adding more of the array primitives to sets - sets are just an "weakly ordered" version of arrays, so basically all of them make sense.

map() is the only troublesome one, because it can produce a smaller set, if you return the same value from multiple iterations. This isn't necessarily bad, but it's surprising.

# Calvin Metcalf (12 years ago)

specific to set (as opposed to ones that work with array) would be the mathematical set operations like union, symmetrical difference (think xor), compliment, and intersection.

# Erik Arvidsson (12 years ago)

I always envisioned that we would create a full fledged iter module and then we would define these functions once and for all.