New collections (Set and Map) methods
See formal spec WIP.
(Semi)relevant previous discussions
- Map#map and Map#filter
- Map.prototype.map and Map.prototype.filter (spec) + Set
- Map: filter/map and more
- Original topic regarding this proposal
- Newer topic regarding this proposal
Motivations
- it's consistent with already familiar and widely used
Array
API (reduced cognitive overhead)- easier refactoring
- certain function become generic
- reduces boilerplate code when dealing with common collection use cases
- no new syntax
- allow developers coming from other languages to use familiar APIs
Adoption
TBA
Quick reference for other languages similar data structures
Set
Map (known also as Dictionary)
TBA
Proposal
This proposal does not change grammar of language.
New methods are added to Set.prototype
.
- Array-like methods. These methods replicates functionality of
Array.prototype
methods:Set.prototype.filter(predicate, thisArg)
Set.prototype.map(fn, thisArg)
Set.prototype.find(fn, thisArg)
Set.prototype.reduce(fn, initialValue)
Set.prototype.join(separator)
Set.prototype.some(predicate, thisArg)
Set.prototype.every(predicate, thisArg)
- New methods:
Set.prototype.addAll(...elements)
- similar toArray.prototype.push
. Adds all of arguments to existingSet
.- Alternative name:
.addEach
- Alternative name:
Set.prototype.deleteAll(...elements)
- reverse ofaddAll
. Remove everyelement
inelements
from existingSet
.- Alternative names:
.deleteEach
- Alternative names:
New methods are added to Map.prototype
.
-
Array-like methods. These methods replicates functionality of
Array.prototype
methods:Map.prototype.filter(predicate, thisArg)
Map.prototype.mapValues(fn, thisArg)
Map.prototype.mapKeys(fn, thisArg)
Map.prototype.reduce(fn, initialValue)
Map.prototype.find(fn, thisArg)
Map.prototype.findKey(fn, thisArg)
Map.prototype.keyOf(searchElement)
Map.prototype.some(predicate, thisArg)
Map.prototype.every(predicate, thisArg)
Map.prototype.includes(searchElement)
Map.prototype.update(key, callbackfn, thunk)
-
New methods:
Map.prototype.deleteAll(...elements)
- similar toSet.prototype.deleteAll
.Map.prototype.merge(...iterables)
- performs in-place update joining arbitrary number of iterables.Map.prototype.update(key, cb [,thunk])
- performs in-place update of single value.
New methods are added to %Map%
.
Map.groupBy(iterable, keyDerivative)
-Map.keyBy(iterable, keyDerivative)
-
New methods are added to WeakSet.prototype
.
- New methods:
WeakSet.prototype.addAll(...elements)
- similar toSet.prototype.addAll
.WeakSet.prototype.deleteAll(...elements)
- similar toSet.prototype.deleteAll
.
New methods are added to WeakMap.prototype
.
- New methods:
WeakMap.prototype.deleteAll(...elements)
- similar toMap.prototype.deleteAll
.
Polyfill
A polyfill is available in the core-js library. You can find it in the ECMAScript proposal section / Stage 1 proposals / New Set and Map methods proposal.
For all new collection methods include this at the top of your entry point.
require('core-js/proposals/collection-methods');
const colors = new Map([['red', '#FF0000'], ['gold', '#FFD700']]);
colors
.mapKeys((value, key) => key.toUpperCase()) // Map { 'RED' => '#FF0000', 'GOLD' => '#FFD700' }
.mapValues(value => value.toLowerCase()); // Map { 'RED' => '#ff0000', 'GOLD' => '#ffd700' }
For a specific method include the needed polyfill directly.
require('core-js/features/set/join');
const mySet = new Set(['Just', 'like', 'an', 'array']);
mySet.join(' '); // Just like an array
Not included in this proposal but worth considering
Set.prototype.flatMap
,Set.prototype.flat
- should be added ifArray.prototype.flatMap
is added to language
%IteratorPrototype%
methods
Why not - Explicit usage of iterators is verbose
- Compare
new Set(set.entries().filter(fn))
toset.filter(fn)
. 19 characters of boilerplate.- Even small codebase can have hundreds occurrences of this pattern - and hundreds places to make a mistake.
- Compare
- User code have no easy way to inherit from
%IteratorPrototype%
Rationales
See rationales.md for details.