New collections methods (original) (raw)
1 Formal informations
- title: New collections methods
- location: https://tc39.github.io/proposal-collection-methods/
- repository: https://github.com/tc39/proposal-collection-methods
- contributors: Michał Wadas, Ecma International
2 Set.prototype methods
2.1 Set.prototype.filter( callbackfn [ , thisArg ] )
When the filter
method is called, the following steps are taken:
- Let O be the this value.
- Perform ? RequireInternalSlot(O, [[SetData]]).
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- Let resultSetData be a new empty List.
- Let entries be O.[[SetData]]
- Let thisSize be the number of elements in O.[[SetData]].
- Let index be 0.
- Repeat, while index < thisSize,
- Let e be O.[[SetData]][index].
- Set index to index + 1.
- If e is not empty, then
- Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, kValue, O »)).
- If selected is true, then:
1. Append e to resultSetData.
- Let result be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
- Set result.[[SetData]] to resultSetData.
- Return result.
2.2 Set.prototype.map( callbackfn [ , thisArg ] )
When the map
method is called, the following steps are taken:
- Let O be the this value.
- Perform ? RequireInternalSlot(O, [[SetData]]).
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- Let resultSetData be a new empty List.
- Let entries be O.[[SetData]]
- Let thisSize be the number of elements in O.[[SetData]].
- Let index be 0.
- Repeat, while index < thisSize,
- Let e be O.[[SetData]][index].
- Set index to index + 1.
- If e is not empty, then
- Let mappedValue be ? Call(callbackfn, thisArg, « kValue, kValue, O »).
- Append mappedValue to resultSetData.
- Let result be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
- Set result.[[SetData]] to resultSetData.
- Return result.
2.3 Set.prototype.find( predicate [ , thisArg ] )
When the find
method is called, the following steps are taken:
- Let O be the this value.
- Perform ? RequireInternalSlot(O, [[SetData]]).
- If IsCallable(predicate) is false, throw a TypeError exception.
- Let entries be O.[[SetData]]
- Let thisSize be the number of elements in O.[[SetData]].
- Let index be 0.
- Repeat, while index < thisSize,
- Let e be O.[[SetData]][index].
- Set index to index + 1.
- If e is not empty, then
- Let testResult be ToBoolean(? Call(predicate, thisArg, « e, e, O »))
- If testResult is true, then return e
- Return undefined.
2.4 Set.prototype.some( predicate [ , thisArg ] )
When the some
method is called, the following steps are taken:
- Let set be the this value.
- If Type(set) is not Object, throw a TypeError exception.
- If set does not have a [[SetData]] internal slot, throw a TypeError exception.
- If IsCallable(predicate) is false, throw a TypeError exception.
- Let entries be O.[[SetData]]
- Let thisSize be the number of elements in O.[[SetData]].
- Let index be 0.
- Repeat, while index < thisSize,
- Let e be O.[[SetData]][index].
- Set index to index + 1.
- If e is not empty, then
- Let testResult be ToBoolean(? Call(predicate, thisArg, « e, e, O »))
- If testResult is true, then return testResult
- Return false.
2.5 Set.prototype.every( predicate [ , thisArg ] )
When the every
method is called, the following steps are taken:
- Let O be the this value.
- Perform ? RequireInternalSlot(O, [[SetData]]).
- If IsCallable(predicate) is false, throw a TypeError exception.
- Let entries be O.[[SetData]]
- Let thisSize be the number of elements in O.[[SetData]].
- Let index be 0.
- Repeat, while index < thisSize,
- Let e be O.[[SetData]][index].
- Set index to index + 1.
- If e is not
empty
, then- Let testResult be ToBoolean(? Call(predicate, thisArg, « e, e, set »))
- If testResult is false, then return false
- Return true.
2.6 Set.prototype.reduce( callbackfn [ , initialValue ] )
When the reduce
method is called, the following steps are taken:
- Let set be the this value.
- If Type(set) is not Object, throw a TypeError exception.
- If set does not have a [[SetData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- Let entries be the List that is set.[[SetData]].
- Let accumulator be undefined
- Let first be true.
- If initialValue is present, then
- Set accumulator to initialValue
- For each e that is an element of entries, in original insertion order, do:
- If e is not
empty
, then- If first be true and initialValue is not present:
1. Set accumulator to e - Else,
1. Set accumulator to ? Call(callbackfn, undefined, « accumulator, e, e, map ») - Set first to false
- If first be true and initialValue is not present:
- If e is not
- If first is true and initialValue is not present, throw TypeError exception.
- Return accumulator.
2.7 Set.prototype.join( [ separator ] )
When the join
method is called, the following steps are taken:
- Let set be the this value.
- If Type(set) is not Object, throw a TypeError exception.
- If set does not have a [[SetData]] internal slot, throw a TypeError exception.
- If separator is undefined, let sep be the single-element String
","
. - Else, let sep be ? ToString(separator).
- Let R be the empty String.
- Let k be false.
- Let entries be O.[[SetData]]
- Let thisSize be the number of elements in O.[[SetData]].
- Let index be 0.
- Repeat, while index < thisSize,
- Let e be O.[[SetData]][index].
- Set index to index + 1.
- If e is not empty, then
- If k is true, let R be the string-concatenation of R and sep.
- Set k to true.
- Let next be ? ToString(e).
- Set R to the string-concatenation of R and next.
- Return R.
2.8 Set.prototype.addAll(...items)
When the addAll
method is called, the following steps are taken:
- Let len be the actual number of arguments passed to this function.
- Let items be the List of arguments passed to this function.
- Let set be the this value.
- If Type(set) is not Object, throw a TypeError exception.
- If set does not have a [[SetData]] internal slot, throw a TypeError exception.
- Let elements be CreateArrayFromList(items).
- Let adder be ? Get(set, "add")
- Return ? AddEntriesFromIterable(set, elements, adder).
The length
property of the addAll
method is 0.
2.9 Set.prototype.deleteAll(...items)
When the deleteAll
method is called, the following steps are taken:
- Let len be the actual number of arguments passed to this function.
- Let items be the List of arguments passed to this function.
- Let set be the this value.
- If Type(set) is not Object, throw a TypeError exception.
- Let k be 0.
- Let remover be ? Get(set, "delete")
- If IsCallable(remover) is false, throw a TypeError exception.
- Let allDeleted be true.
- Repeat while k < len
- Let value be items[k].
- Let wasDeleted be Call(remover, set, value)
- Set
allDeleted
to beallDeleted
&&wasDeleted
- Increase k by 1.
- Return ToBoolean(
allDeleted
);
3 Map.prototype methods
3.1 Map.prototype.mapValues( callbackfn, [ thisArg ] )
Editor's Note
This code serves as placeholder until formal spec is written for this method.
function mapValues(callbackFn, thisArg) {
assert(isObject(this), 'this is not an object');
assert(isCallable(callbackFn), 'callback is not a function');
const Ctor = SpeciesConstructor(this, Map);
const retObj = new Ctor();
const _set = retObj.set;
for(const [key, value] of this) {
const newValue = Reflect.apply(callbackFn, thisArg, [value, key, this])
Reflect.apply(_set, retObj, [key, newValue]);
}
return retObj;
}
3.2 Map.prototype.mapKeys( callbackfn, [ thisArg ] )
Editor's Note
This code serves as placeholder until formal spec is written for this method.
function mapKeys(callbackFn, thisArg) {
assert(isObject(this), 'this is not an object');
assert(isCallable(callbackFn), 'callback is not a function');
const Ctor = SpeciesConstructor(this, Map);
const retObj = new Ctor();
const _set = retObj.set;
for(const [key, value] of this) {
const newKey = Reflect.apply(callbackFn, thisArg, [value, key, this])
Reflect.apply(_set, retObj, [newKey, value]);
}
return retObj;
}
3.3 Map.prototype.filter( callbackfn, [ thisArg ] )
Editor's Note
This code serves as placeholder until formal spec is written for this method.
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- If thisArg was supplied, let T be thisArg; else let T be undefined.
- Let Ctr be ? SpeciesConstructor(map, %Map%)
- Let newMap be ? Construct(Ctr)
- Let adder be ? Get(newSet, "set")
- If IsCallable(adder) is false, throw a TypeError.
- Let entries be the List that is map.[[MapData]]
- Let newMapData be new empty List.
- For each Record { [[Key]], [[Value]] } p that is an element of entries, do
- If p.[[Key]] is not empty, then
- Let key be p.[[Key]]
- Let value be p.[[Value]]
- Let selected be ToBoolean(? Call(callbackfn, T, « value, key, map »))
- If selected is true, then
1. Let pair be CreateArrayFromList(« value, key »)
2. Append pair as last element to newMapData.
- If p.[[Key]] is not empty, then
- Return ? AddEntriesFromIterable(map, CreateArrayFromList(newMapData), adder).
3.4 Map.prototype.find( callbackfn [ , thisArg ] )
When the find
method is called, the following steps are taken:
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- If thisArg was supplied, let T be thisArg; else let T be undefined.
- Let entries be the List that is map.[[MapData]].
- For each Record { [[Key]], [[Value]] } e that is an element of entries, in original key insertion order, do:
- If e.[[Key]] is not empty, then
- Let testResult be ToBoolean(? Call(callbackfn, T, « e.[[Value]], e.[[Key]], map »)).
- If testResult is true, then return e.[[Value]].
- If e.[[Key]] is not empty, then
- Return undefined.
3.5 Map.prototype.findKey( callbackfn [ , thisArg ] )
When the findKey
method is called, the following steps are taken:
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- If thisArg was supplied, let T be thisArg; else let T be undefined.
- Let entries be the List that is map.[[MapData]].
- For each Record { [[Key]], [[Value]] } e that is an element of entries, in original key insertion order, do:
- If e.[[Key]] is not empty, then
- Let testResult be ToBoolean(? Call(callbackfn, T, « e.[[Value]], e.[[Key]], map »)).
- If testResult is true, then return e.[[Key]].
- If e.[[Key]] is not empty, then
- Return undefined.
3.6 Map.prototype.keyOf( searchElement )
When the keyOf
method is called, the following steps are taken:
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- Let entries be the List that is map.[[MapData]].
- For each Record { [[Key]], [[Value]] } e that is an element of entries, in original key insertion order, do:
- If e.[[Key]] is not empty, then
- Let same be the result of performing Strict Equality Comparison searchElement === e.[[Value]].
- If same is true, then return e.[[Key]].
- If e.[[Key]] is not empty, then
- Return undefined.
3.7 Map.prototype.some( callbackfn [ , thisArg ] )
When the some
method is called, the following steps are taken:
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- If thisArg was supplied, let T be thisArg; else let T be undefined.
- Let entries be the List that is map.[[MapData]].
- For each Record { [[Key]], [[Value]] } e that is an element of entries, in original key insertion order, do:
- If e.[[Key]] is not empty, then
- Let testResult be ToBoolean(? Call(callbackfn, T, « e.[[Value]], e.[[Key]], map »))
- If testResult is true, then return true
- If e.[[Key]] is not empty, then
- Return false.
3.8 Map.prototype.every( predicate [ , thisArg ] )
When the every
method is called, the following steps are taken:
- Let M be the this value.
- Perform ? RequireInternalSlot(M, [[MapData]]).
- If IsCallable(predicate) is **false*, throw a *TypeError exception.
- Let entries be the List that is map.[[MapData]].
- For each Record { [[Key]], [[Value]] } e of M.[[MapData]], do
- If e.[[Key]] is not empty, then
- Let testResult be ToBoolean(? Call(predicate, T, « e.[[Value]], e.[[Key]], map »))
- If testResult is false, then return false
- If e.[[Key]] is not empty, then
- Return true.
3.9 Map.prototype.includes( searchElement )
When the includes
method is called, the following steps are taken:
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- Let entries be the List that is map.[[MapData]].
- For each Record { [[Key]], [[Value]] } e that is an element of entries, in original key insertion order, do:
- If e.[[Key]] is not empty, then
- If SameValueZero(searchElement, e.[[Value]]) is true, return true.
- If e.[[Key]] is not empty, then
- Return false.
3.10 Map.prototype.reduce( callbackfn [ , initialValue ] )
When the reduce
method is called, the following steps are taken:
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- Let entries be the List that is map.[[MapData]].
- Let accumulator be undefined
- Let first be true.
- If initialValue is present, then
- Set accumulator to initialValue
- For each Record { [[Key]], [[Value]] } e that is an element of entries, in original key insertion order, do:
- If e.[[Key]] is not empty, then
- If first be true and initialValue is not present:
1. Set accumulator to e.[[Value]] - Else,
1. Set accumulator to ? Call(callbackfn, undefined, « accumulator, e.[[Value]], e.[[Key]], map ») - Set first to false
- If first be true and initialValue is not present:
- If e.[[Key]] is not empty, then
- If first is true and initialValue is not present, throw TypeError exception.
- Return accumulator.
3.11 Map.prototype.merge(... iterables )
Editor's Note
This code serves as placeholder until formal spec is written for this method.
function merge(...iterables) {
assert(isObject(this), 'this is not an object');
assert(this instanceof Map, 'this is not a Map instance');
for(const iterable of iterables) {
for(const [key, value] of iterable) {
this.set(key, value);
}
}
return this;
}
3.12 Map.prototype.deleteAll(...items)
When the deleteAll
method is called, the following steps are taken:
The length
property of the deleteAll
method is 0.
- Let len be the actual number of arguments passed to this function.
- Let items be the List of arguments passed to this function.
- Let map be the this value.
- If Type(map) is not Object, throw a TypeError exception.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- Let k be 0.
- Let remover be ? Get(map, "delete")
- If IsCallable(remover) is false, throw a TypeError exception.
- Repeat while k < len
- Let value be items[k].
- Call(remover, map, value)
- Increase k by 1.
- Return map.
3.13 Map.prototype.update(key, callback [, thunk])
Editor's Note
This code serves as placeholder until formal spec is written for this method.
function update(key, cb, thunk) {
assert(isObject(this), 'this is not an object');
assert(isCallable(callbackFn), 'callback is not a function');
asset(isMap(this), 'this is not a Map instance');
const isPresentInMap = this.has(key);
if (isPresentInMap === false && arguments.length < 3) {
throw new Error('Invalid!');
}
const value = isPresentInMap ? this.get(key) : thunk(key, this);
const newValue = cb(value, key, this);
this.set(key, newValue);
return this;
}
4 Map static methods
4.1 Map.keyBy( iterable, callbackfn)
When the keyBy
method is called, the following steps are taken:
- Let C be the this value.
- If IsConstructor(C) is true
- Let map be ? Construct(C)
- Else,
- Throw a TypeError.
- If map does not have a [[MapData]] internal slot, throw a TypeError exception.
- If IsCallable(callbackfn) is false, throw a TypeError exception.
- Let set be ? Get(map, "set")
- Let iteratorRecord be ? GetIterator(iterable).
- Repeat,
- Let next be ? IteratorStep(iteratorRecord).
- If next is false, return map.
- Let item be ? IteratorValue(next).
- Let key be Call(callbackfn, null, « item »)
- Let status be Call(set, map, « key.[[Value]], value.[[Value]] »).
- If status is an abrupt completion, return ? IteratorClose(iteratorRecord, status).
5 WeakSet.prototype.addAll(...items)
When the addAll
method is called, the following steps are taken:
- Let len be the actual number of arguments passed to this function.
- Let items be the List of arguments passed to this function.
- Let weakset be the this value.
- If Type(weakset) is not Object, throw a TypeError exception.
- Let k be 0.
- Let adder be ? Get(weakset, "add")
- If IsCallable(adder) is false, throw a TypeError exception.
- Repeat while k < len
- Let kValue be items[k].
- Call(adder, weakset, kValue)
- Increase k by 1.
- Return weakset.
The length
property of the addAll
method is 0.
6 WeakSet.prototype.deleteAll(...items)
When the deleteAll
method is called, the following steps are taken:
- Let len be the actual number of arguments passed to this function.
- Let items be the List of arguments passed to this function.
- Let weakset be the this value.
- If Type(weakset) is not Object, throw a TypeError exception.
- Let k be 0.
- Let remover be ? Get(weakset, "delete")
- If IsCallable(remover) is false, throw a TypeError exception.
- Repeat while k < len
- Let value be items[k].
- Call(remover, weakset, value)
- Increase k by 1.
- Return weakset.
The length
property of the deleteAll
method is 0.
7 WeakMap.prototype.deleteAll(...items)
When the deleteAll
method is called, the following steps are taken:
- Let len be the actual number of arguments passed to this function.
- Let items be the List of arguments passed to this function.
- Let weakmap be the this value.
- If Type(weakmap) is not Object, throw a TypeError exception.
- Let k be 0.
- Let remover be ? Get(weakmap, "delete")
- If IsCallable(remover) is false, throw a TypeError exception.
- Repeat while k < len
- Let value be items[k].
- Call(remover, weakmap, value)
- Increase k by 1.
- Return weakmap.
The length
property of the deleteAll
method is 0.
A Copyright & Software License
Copyright Notice
© 2024 Michał Wadas, Ecma International
Software License
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.