Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Commit

Permalink
Convert to static factory methods
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell authored and ljharb committed Nov 29, 2022
1 parent c8ecd05 commit 1d06188
Showing 1 changed file with 74 additions and 83 deletions.
157 changes: 74 additions & 83 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -18,82 +18,99 @@ location: https://tc39.es/proposal-array-grouping/
</p>
</emu-clause>

<emu-clause id="sec-properties-of-the-array-prototype-object">
<h1>Properties of the Array Prototype Object (<a href="https://tc39.es/ecma262/#sec-properties-of-the-array-prototype-object">22.1.3</a>)</h1>
<emu-clause id="sec-properties-of-the-object-constructor">
<h1>Properties of the Object Constructor (<a href="https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-properties-of-the-object-constructor">20.1.2</a>)</h1>

<ins class="block">
<emu-clause id="sec-array.prototype.group">
<h1>Array.prototype.group ( _callbackfn_ [ , _thisArg_ ] )</h1>
<emu-clause id="sec-object.groupby">
<h1>Object.groupBy ( _items_, _callbackfn_ )</h1>
<emu-note>
<p>_callbackfn_ should be a function that accepts three arguments. `group` calls _callbackfn_ once for each element in the array, in ascending order, and constructs a new object of arrays. Each value returned by _callbackfn_ is coerced to a property key, and the associated element is included in the array in the constructed object according to this property key.</p>
<p>If a _thisArg_ parameter is provided, it will be used as the *this* value for each invocation of _callbackfn_. If it is not provided, *undefined* is used instead.</p>
<p>_callbackfn_ is called with three arguments: the value of the element, the index of the element, and the object being traversed.</p>
<p>`group` does not directly mutate the object on which it is called but the object may be mutated by the calls to _callbackfn_.</p>
<p>The range of elements processed by `group` is set before the first call to _callbackfn_. Elements which are appended to the array after the call to `group` begins will not be visited by _callbackfn_. If existing elements of the array are changed their value as passed to _callbackfn_ will be the value at the time `group` visits them; elements that are deleted after the call to `group` begins and before being visited are still visited and are either looked up from the prototype or are *undefined*.</p>
<p>The return value of `group` is an object that does not inherit from _Object.prototype_.</p>
<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 of arrays. Each value returned by _callbackfn_ is coerced to a property key, and the associated element is included in the array in the constructed object according to this property key.</p>
<p>_callbackfn_ is called with two arguments: the value of the element and the index of the element.</p>
<p>The return value of `groupBy` is an object that does not inherit from %Object.prototype%.</p>
</emu-note>
<p>When the `group` method is called with one or two arguments, the following steps are taken:</p>
<p>When the `groupBy` method is called with two arguments, the following steps are taken:</p>
<emu-alg>
1. Let _O_ be ? ToObject(*this* value).
1. Let _len_ be ? LengthOfArrayLike(_O_).
1. If IsCallable(_callbackfn_) is *false*, throw a *TypeError* exception.
1. Let _k_ be 0.
1. Let _groups_ be a new empty List.
1. Repeat, while _k_ &lt; _len_
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Let _kValue_ be ? Get(_O_, _Pk_).
1. Let _propertyKey_ be ? ToPropertyKey(? Call(_callbackfn_, _thisArg_, &laquo; _kValue_, 𝔽(_k_), _O_ &raquo;)).
1. Perform AddValueToKeyedGroup(_groups_, _propertyKey_, _kValue_).
1. Set _k_ to _k_ + 1.
1. Let _groups_ be ? GroupBy(_items_, _callbackfn_, ~property~).
1. Let _obj_ be OrdinaryObjectCreate(*null*).
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
1. Let _elements_ be CreateArrayFromList(_g_.[[Elements]]).
1. Perform ! CreateDataPropertyOrThrow(_obj_, _g_.[[Key]], _elements_).
1. Return _obj_.
</emu-alg>
<emu-note>
<p>The `group` function is intentionally generic; it does not require that its *this* value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.</p>
</emu-note>
</emu-clause>
</ins>
</emu-clause>

<emu-clause id="sec-properties-of-the-map-constructor">
<h1>Properties of the Map Constructor (<a href="https://tc39.es/ecma262/multipage/keyed-collections.html#sec-properties-of-the-map-constructor">24.1.2</a>)</h1>

<ins class="block">
<emu-clause id="sec-array.prototype.grouptomap">
<h1>Array.prototype.groupToMap ( _callbackfn_ [ , _thisArg_ ] )</h1>
<emu-clause id="sec-map.groupby">
<h1>Map.groupBy ( _items_, _callbackfn_ )</h1>
<emu-note>
<p>_callbackfn_ should be a function that accepts three arguments. `groupToMap` calls _callbackfn_ once for each element in the array, in ascending order, and constructs a new Map of arrays. Each value returned by _callbackfn_ is used as a key in the Map, and the associated element is included in the array in the constructed Map according to this key.</p>
<p>If a _thisArg_ parameter is provided, it will be used as the *this* value for each invocation of _callbackfn_. If it is not provided, *undefined* is used instead.</p>
<p>_callbackfn_ is called with three arguments: the value of the element, the index of the element, and the object being traversed.</p>
<p>`groupToMap` does not directly mutate the object on which it is called but the object may be mutated by the calls to _callbackfn_.</p>
<p>The range of elements processed by `groupToMap` is set before the first call to _callbackfn_. Elements which are appended to the array after the call to `groupToMap` begins will not be visited by _callbackfn_. If existing elements of the array are changed their value as passed to _callbackfn_ will be the value at the time `groupToMap` visits them; elements that are deleted after the call to `groupToMap` begins and before being visited are still visited and are either looked up from the prototype or are *undefined*.</p>
<p>The return value of `groupToMap` is a Map.</p>
<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, and the associated element is included in the array in the constructed Map according to this key.</p>
<p>_callbackfn_ is called with two arguments: the value of the element and the index of the element.</p>
<p>The return value of `groupBy` is a Map.</p>
</emu-note>
<p>When the `groupToMap` method is called with one or two arguments, the following steps are taken:</p>
<p>When the `groupBy` method is called with two arguments, the following steps are taken:</p>
<emu-alg>
1. Let _O_ be ? ToObject(*this* value).
1. Let _len_ be ? LengthOfArrayLike(_O_).
1. If IsCallable(_callbackfn_) is *false*, throw a *TypeError* exception.
1. Let _k_ be 0.
1. Let _groups_ be a new empty List.
1. Repeat, while _k_ &lt; _len_
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Let _kValue_ be ? Get(_O_, _Pk_).
1. Let _key_ be ? Call(_callbackfn_, _thisArg_, &laquo; _kValue_, 𝔽(_k_), _O_ &raquo;).
1. If _key_ is *-0*<sub>𝔽</sub>, set _key_ to *+0*<sub>𝔽</sub>.
1. Perform AddValueToKeyedGroup(_groups_, _key_, _kValue_).
1. Set _k_ to _k_ + 1.
1. Let _groups_ be ? GroupBy(_items_, _callbackfn_, ~zero~).
1. Let _map_ be ! Construct(%Map%).
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
1. Let _elements_ be CreateArrayFromList(_g_.[[Elements]]).
1. Let _entry_ be the Record { [[Key]]: _g_.[[Key]], [[Value]]: _elements_ }.
1. Append _entry_ as the last element of _map_.[[MapData]].
1. Return _map_.
</emu-alg>
<emu-note>
<p>The `groupToMap` function is intentionally generic; it does not require that its *this* value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.</p>
</emu-note>
</emu-clause>
</ins>
</emu-clause>

<emu-clause id="sec-group-by-helpers">
<h1>Group By Helpers</h1>

<ins class="block">
<emu-clause id="sec-group-by" type="abstract operation">
<h1>
GroupBy (
_items_: an ECMAScript language value,
_callbackfn_: an ECMAScript language value,
_coercion_: ~property~ or ~zero~,
): 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
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Perform ? RequireObjectCoercible(_items_).
1. If IsCallable(_callbackfn_) is *false*, throw a *TypeError* exception.
1. Let _groups_ be a new empty List.
1. Let _iteratorRecord_ be ? GetIterator(_items_).
1. Let _k_ be 0.
1. Repeat,
1. If _k_ ≥ 2<sup>53</sup> - 1, then
1. Let _error_ be ThrowCompletion(a newly created *TypeError* object).
1. Return ? IteratorClose(_iteratorRecord_, _error_).
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Let _next_ be ? IteratorStep(_iteratorRecord_).
1. If _next_ is *false*, then
1. Return _groups_.
1. Let _value_ be ? IteratorValue(_next_).
1. Let _key_ be Completion(Call(_callbackfn_, *undefined*, &laquo; _value_, 𝔽(_k_) &raquo;)).
1. IfAbruptCloseIterator(_key_, _iteratorRecord_).
1. If _coercion_ is ~property~, then
1. Set _key_ to Completion(ToPropertyKey(_key_)).
1. IfAbruptCloseIterator(_key_, _iteratorRecord_).
1. Else,
1. Assert: _coercion_ is ~zero~.
1. If _key_ is *-0*<sub>𝔽</sub>, set _key_ to *+0*<sub>𝔽</sub>.
1. Perform AddValueToKeyedGroup(_groups_, _key_, _value_).
1. Set _k_ to _k_ + 1.
</emu-alg>
</emu-clause>
</ins>

<ins class="block">
<emu-clause id="sec-add-value-to-keyed-group" type="abstract operation">
<h1>
AddValueToKeyedGroup (
Expand All @@ -105,41 +122,15 @@ location: https://tc39.es/proposal-array-grouping/
<dl class="header">
</dl>
<emu-alg>
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
1. If SameValue(_g_.[[Key]], _key_) is *true*, then
1. Assert: exactly one element of _groups_ meets this criteria.
1. Append _value_ as the last element of _g_.[[Elements]].
1. Return ~unused~.
1. Let _group_ be the Record { [[Key]]: _key_, [[Elements]]: &laquo; _value_ &raquo; }.
1. Append _group_ as the last element of _groups_.
1. Return ~unused~.
1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do
1. If SameValue(_g_.[[Key]], _key_) is *true*, then
1. Assert: exactly one element of _groups_ meets this criteria.
1. Append _value_ as the last element of _g_.[[Elements]].
1. Return ~unused~.
1. Let _group_ be the Record { [[Key]]: _key_, [[Elements]]: &laquo; _value_ &raquo; }.
1. Append _group_ as the last element of _groups_.
1. Return ~unused~.
</emu-alg>
</emu-clause>
</ins>

<emu-clause id="sec-array.prototype-@@unscopables">
<h1>Array.prototype [ @@unscopables ]</h1>
<p>The initial value of the @@unscopables data property is an object created by the following steps:</p>
<emu-alg>
1. Let _unscopableList_ be OrdinaryObjectCreate(*null*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"at"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"copyWithin"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"entries"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"fill"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"find"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"findIndex"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"flat"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"flatMap"*, *true*).
1. <ins>Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"group"*, *true*).</ins>
1. <ins>Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"groupToMap"*, *true*).</ins>
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"includes"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"keys"*, *true*).
1. Perform ! CreateDataPropertyOrThrow(_unscopableList_, *"values"*, *true*).
1. Return _unscopableList_.
</emu-alg>
<p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
<emu-note>
<p>The own property names of this object are property names that were not included as standard properties of `Array.prototype` prior to the ECMAScript 2015 specification. These names are ignored for `with` statement binding purposes in order to preserve the behaviour of existing code that might use one of these names as a binding in an outer scope that is shadowed by a `with` statement whose binding object is an Array.</p>
</emu-note>
</emu-clause>
</emu-clause>

0 comments on commit 1d06188

Please sign in to comment.