New Set methods - again

Peter Jaszkowiak p.jaszkow at gmail.com
Mon Jul 31 01:31:39 UTC 2017


> its `forEach` method does call its callback with indices.

This is incorrect. Both the `value` and `key` arguments are equal for Sets,
equal to the current element in the Set.

>From a different reply which I mistakenly forget to CC esdiscuss

> True, Sets are technically ordered by insertion order in their iterator,
but they aren't indexed, so certain elements can't be selected like with an
Array, and they can't be sorted. `reduce`, in my opinion, still makes
little sense given those facts. Especially since the most common use of
reduce, in my experience, is to create an object from an array of pairs,
this could be handled better by just `new Map(...your_set_of_pairs)`

Reduce seems to make more sense as an ordered operation, but in an attempt
to justify adding reduce, here's a use case for an unordered reduce that
can't be solved with any other method proposed here, including `.flatMap`.

```js
const product = numbers.reduce((prev, x) => prev * x, 1);
```

This can't be done without reduce, unless something like `Math.product`
gets introduced, which I think it should, but what about multiple
exponents? What I want to do a^b^c^d^e^f etc, I'd still need something like
reduce for that.

I tried to think of a more complex use case for an index-less `reduce`
method, but I couldn't. I thought maybe combinations of elements, but
without a way to select a certain subset like `Array#slice`, it's not
simple at all. For instance, with an array, you can do the following:

```js
// this works because we have a placeholder `i`
Array.isArray(players) === true;

players.reduce((matches, player, i) => {
  return [...matches, ...players.slice(i + 1).map(vsPlayer => new
Match(player, vsPlayer)));
}, []);

// without the index it is not trivial
// it's also much less efficient, probably better to just cast to an Array
first
Set.isSet(players) === true;

players.reduce((matches, player, key) => {
  key === player;
  return [...matches, ...players.filter(
  vsPlayer => matches.some(match => !match.players.includes(player) ||
!match.players.includes(vsPlayer))
  ).map(vsPlayer => new Match(player, vsPlayer))];
}, new Set());
```

The only other orderless operatons that I can think of are things like
summing or multiplying numbers, which I do think should be added to the
standard library as `Math.sum` and `Math.product`, but it should be
possible to do without. So in that case, I guess I agree that `.reduce`
should exist on `Set` and `Map`.

I don't see many use cases for `.reduce`, but for consistency, it should be
added.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170730/5f9a1fdb/attachment.html>


More information about the es-discuss mailing list