Skip to content

Commit 671eaca

Browse files
committed
Normative: add Object.groupBy and Map.groupBy (#3176)
See https://tc39.es/proposal-array-grouping/
1 parent 82c99bb commit 671eaca

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

spec.html

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6769,6 +6769,65 @@ <h1>
67696769
1. Return ~unused~.
67706770
</emu-alg>
67716771
</emu-clause>
6772+
6773+
<emu-clause id="sec-add-value-to-keyed-group" type="abstract operation">
6774+
<h1>
6775+
AddValueToKeyedGroup (
6776+
_groups_: a List of Records with fields [[Key]] (an ECMAScript language value) and [[Elements]] (a List of ECMAScript language values),
6777+
_key_: an ECMAScript language value,
6778+
_value_: an ECMAScript language value,
6779+
): ~unused~
6780+
</h1>
6781+
<dl class="header">
6782+
</dl>
6783+
<emu-alg>
6784+
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
6785+
1. If SameValue(_g_.[[Key]], _key_) is *true*, then
6786+
1. Assert: Exactly one element of _groups_ meets this criterion.
6787+
1. Append _value_ to _g_.[[Elements]].
6788+
1. Return ~unused~.
6789+
1. Let _group_ be the Record { [[Key]]: _key_, [[Elements]]: « _value_ » }.
6790+
1. Append _group_ to _groups_.
6791+
1. Return ~unused~.
6792+
</emu-alg>
6793+
</emu-clause>
6794+
6795+
<emu-clause id="sec-groupby" type="abstract operation">
6796+
<h1>
6797+
GroupBy (
6798+
_items_: an ECMAScript language value,
6799+
_callbackfn_: an ECMAScript language value,
6800+
_keyCoercion_: ~property~ or ~zero~,
6801+
): either a normal completion containing a List of Records with fields [[Key]] (an ECMAScript language value) and [[Elements]] (a List of ECMAScript language values), or a throw completion
6802+
</h1>
6803+
<dl class="header">
6804+
</dl>
6805+
<emu-alg>
6806+
1. Perform ? RequireObjectCoercible(_items_).
6807+
1. If IsCallable(_callbackfn_) is *false*, throw a *TypeError* exception.
6808+
1. Let _groups_ be a new empty List.
6809+
1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~).
6810+
1. Let _k_ be 0.
6811+
1. Repeat,
6812+
1. If _k_ ≥ 2<sup>53</sup> - 1, then
6813+
1. Let _error_ be ThrowCompletion(a newly created *TypeError* object).
6814+
1. Return ? IteratorClose(_iteratorRecord_, _error_).
6815+
1. Let _next_ be ? IteratorStep(_iteratorRecord_).
6816+
1. If _next_ is *false*, then
6817+
1. Return _groups_.
6818+
1. Let _value_ be ? IteratorValue(_next_).
6819+
1. Let _key_ be Completion(Call(_callbackfn_, *undefined*, « _value_, 𝔽(_k_) »)).
6820+
1. IfAbruptCloseIterator(_key_, _iteratorRecord_).
6821+
1. If _keyCoercion_ is ~property~, then
6822+
1. Set _key_ to Completion(ToPropertyKey(_key_)).
6823+
1. IfAbruptCloseIterator(_key_, _iteratorRecord_).
6824+
1. Else,
6825+
1. Assert: _keyCoercion_ is ~zero~.
6826+
1. If _key_ is *-0*<sub>𝔽</sub>, set _key_ to *+0*<sub>𝔽</sub>.
6827+
1. Perform AddValueToKeyedGroup(_groups_, _key_, _value_).
6828+
1. Set _k_ to _k_ + 1.
6829+
</emu-alg>
6830+
</emu-clause>
67726831
</emu-clause>
67736832

67746833
<emu-clause id="sec-operations-on-iterator-objects">
@@ -29795,6 +29854,24 @@ <h1>Object.getPrototypeOf ( _O_ )</h1>
2979529854
</emu-alg>
2979629855
</emu-clause>
2979729856

29857+
<emu-clause id="sec-object.groupby">
29858+
<h1>Object.groupBy ( _items_, _callbackfn_ )</h1>
29859+
<emu-note>
29860+
<p>_callbackfn_ should be a function that accepts two arguments. `groupBy` calls _callbackfn_ once for each element in _items_, in ascending order, and constructs a new object. Each value returned by _callbackfn_ is coerced to a property key. For each such property key, the result object has a property whose key is that property key and whose value is an array containing all the elements for which the _callbackfn_ return value coerced to that key.</p>
29861+
<p>_callbackfn_ is called with two arguments: the value of the element and the index of the element.</p>
29862+
<p>The return value of `groupBy` is an object that does not inherit from %Object.prototype%.</p>
29863+
</emu-note>
29864+
<p>This function performs the following steps when called:</p>
29865+
<emu-alg>
29866+
1. Let _groups_ be ? GroupBy(_items_, _callbackfn_, ~property~).
29867+
1. Let _obj_ be OrdinaryObjectCreate(*null*).
29868+
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
29869+
1. Let _elements_ be CreateArrayFromList(_g_.[[Elements]]).
29870+
1. Perform ! CreateDataPropertyOrThrow(_obj_, _g_.[[Key]], _elements_).
29871+
1. Return _obj_.
29872+
</emu-alg>
29873+
</emu-clause>
29874+
2979829875
<emu-clause id="sec-object.hasown">
2979929876
<h1>Object.hasOwn ( _O_, _P_ )</h1>
2980029877
<p>This function performs the following steps when called:</p>
@@ -41755,6 +41832,25 @@ <h1>Properties of the Map Constructor</h1>
4175541832
<li>has the following properties:</li>
4175641833
</ul>
4175741834

41835+
<emu-clause id="sec-map.groupby">
41836+
<h1>Map.groupBy ( _items_, _callbackfn_ )</h1>
41837+
<emu-note>
41838+
<p>_callbackfn_ should be a function that accepts two arguments. `groupBy` calls _callbackfn_ once for each element in _items_, in ascending order, and constructs a new Map of arrays. Each value returned by _callbackfn_ is used as a key in the Map. For each such key, the result Map has an entry whose key is that key and whose value is an array containing all the elements for which _callbackfn_ returned that key.</p>
41839+
<p>_callbackfn_ is called with two arguments: the value of the element and the index of the element.</p>
41840+
<p>The return value of `groupBy` is a Map.</p>
41841+
</emu-note>
41842+
<p>This function performs the following steps when called:</p>
41843+
<emu-alg>
41844+
1. Let _groups_ be ? GroupBy(_items_, _callbackfn_, ~zero~).
41845+
1. Let _map_ be ! Construct(%Map%).
41846+
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
41847+
1. Let _elements_ be CreateArrayFromList(_g_.[[Elements]]).
41848+
1. Let _entry_ be the Record { [[Key]]: _g_.[[Key]], [[Value]]: _elements_ }.
41849+
1. Append _entry_ to _map_.[[MapData]].
41850+
1. Return _map_.
41851+
</emu-alg>
41852+
</emu-clause>
41853+
4175841854
<emu-clause id="sec-map.prototype">
4175941855
<h1>Map.prototype</h1>
4176041856
<p>The initial value of `Map.prototype` is the Map prototype object.</p>

0 commit comments

Comments
 (0)