diff --git a/index.html b/index.html index d96dd1d..d886de3 100644 --- a/index.html +++ b/index.html @@ -2264,7 +2264,7 @@ <h1><span class="secnum">2.1</span> Array.prototype.groupBy ( <var>callbackfn</v <p>The return value of <code>groupBy</code> is an object that does not inherit from <var>Object.prototype</var>.</p> </div></emu-note> <p>When the <code>groupBy</code> method is called with one or two arguments, the following steps are taken:</p> - <emu-alg><ol><li>Let <var>O</var> be ? <emu-xref aoid="ToObject" id="_ref_0"><a href="https://tc39.es/ecma262/#sec-toobject">ToObject</a></emu-xref>(<emu-val>this</emu-val> value).</li><li>Let <var>len</var> be ? <emu-xref aoid="LengthOfArrayLike" id="_ref_1"><a href="https://tc39.es/ecma262/#sec-lengthofarraylike">LengthOfArrayLike</a></emu-xref>(<var>O</var>).</li><li>If <emu-xref aoid="IsCallable" id="_ref_2"><a href="https://tc39.es/ecma262/#sec-iscallable">IsCallable</a></emu-xref>(<var>callbackfn</var>) is <emu-val>false</emu-val>, throw a <emu-val>TypeError</emu-val> exception.</li><li>Let <var>k</var> be 0.</li><li>Let <var>obj</var> be ! OrdinaryObjectCreate(null).</li><li><emu-xref href="#assert"><a href="https://tc39.es/ecma262/#assert">Assert</a></emu-xref>: <var>obj</var> is an extensible ordinary object with no own properties.</li><li>Repeat, while <var>k</var> < <var>len</var><ol><li>Let <var>Pk</var> be ! <emu-xref aoid="ToString" id="_ref_3"><a href="https://tc39.es/ecma262/#sec-tostring">ToString</a></emu-xref>(<var>k</var>).</li><li>Let <var>kValue</var> be ? <emu-xref aoid="Get" id="_ref_4"><a href="https://tc39.es/ecma262/#sec-get-o-p">Get</a></emu-xref>(<var>O</var>, <var>Pk</var>).</li><li>Let <var>propertyKey</var> be ? <emu-xref aoid="ToPropertyKey" id="_ref_5"><a href="https://tc39.es/ecma262/#sec-topropertykey">ToPropertyKey</a></emu-xref>(? <emu-xref aoid="Call" id="_ref_6"><a href="https://tc39.es/ecma262/#sec-call">Call</a></emu-xref>(<var>callbackfn</var>, <var>thisArg</var>, « <var>kValue</var>, <var>k</var>, <var>O</var> »)).</li><li>Let <var>seen</var> be ? <emu-xref aoid="HasOwnProperty" id="_ref_7"><a href="https://tc39.es/ecma262/#sec-hasownproperty">HasOwnProperty</a></emu-xref>(<var>obj</var>, <var>propertyKey</var>).</li><li>If <var>seen</var> is <emu-val>true</emu-val>, then<ol><li>Let <var>arr</var> be ! <emu-xref aoid="Get" id="_ref_8"><a href="https://tc39.es/ecma262/#sec-get-o-p">Get</a></emu-xref>(<var>obj</var>, <var>propertyKey</var>).</li></ol></li><li>Else<ol><li>Let <var>arr</var> be ? <emu-xref aoid="ArraySpeciesCreate" id="_ref_9"><a href="https://tc39.es/ecma262/#sec-arrayspeciescreate">ArraySpeciesCreate</a></emu-xref>(O, 0).</li><li>Perform ! <emu-xref aoid="CreateDataPropertyOrThrow" id="_ref_10"><a href="https://tc39.es/ecma262/#sec-createdatapropertyorthrow">CreateDataPropertyOrThrow</a></emu-xref>(<var>obj</var>, <var>propertyKey</var>, <var>arr</var>).</li></ol></li><li>Perform ? <emu-xref aoid="Call" id="_ref_11"><a href="https://tc39.es/ecma262/#sec-call">Call</a></emu-xref>(%Array.prototype.push%, <var>arr</var>, <var>kValue</var>).</li><li>Set <var>k</var> to <var>k</var> + 1.</li></ol></li><li>Return <var>obj</var>.</li></ol></emu-alg> + <emu-alg><ol><li>Let <var>O</var> be ? <emu-xref aoid="ToObject" id="_ref_0"><a href="https://tc39.es/ecma262/#sec-toobject">ToObject</a></emu-xref>(<emu-val>this</emu-val> value).</li><li>Let <var>len</var> be ? <emu-xref aoid="LengthOfArrayLike" id="_ref_1"><a href="https://tc39.es/ecma262/#sec-lengthofarraylike">LengthOfArrayLike</a></emu-xref>(<var>O</var>).</li><li>If <emu-xref aoid="IsCallable" id="_ref_2"><a href="https://tc39.es/ecma262/#sec-iscallable">IsCallable</a></emu-xref>(<var>callbackfn</var>) is <emu-val>false</emu-val>, throw a <emu-val>TypeError</emu-val> exception.</li><li>Let <var>k</var> be 0.</li><li>Let <var>groups</var> be a new empty <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">List</a></emu-xref>.</li><li>Repeat, while <var>k</var> < <var>len</var><ol><li>Let <var>Pk</var> be ! <emu-xref aoid="ToString" id="_ref_3"><a href="https://tc39.es/ecma262/#sec-tostring">ToString</a></emu-xref>(<var>k</var>).</li><li>Let <var>kValue</var> be ? <emu-xref aoid="Get" id="_ref_4"><a href="https://tc39.es/ecma262/#sec-get-o-p">Get</a></emu-xref>(<var>O</var>, <var>Pk</var>).</li><li>Let <var>propertyKey</var> be ? <emu-xref aoid="ToPropertyKey" id="_ref_5"><a href="https://tc39.es/ecma262/#sec-topropertykey">ToPropertyKey</a></emu-xref>(? <emu-xref aoid="Call" id="_ref_6"><a href="https://tc39.es/ecma262/#sec-call">Call</a></emu-xref>(<var>callbackfn</var>, <var>thisArg</var>, « <var>kValue</var>, <var>k</var>, <var>O</var> »)).</li><li>Let <var>group</var> be <emu-const>empty</emu-const>.</li><li>For each <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> { [[Key]], [[Elements]] } <var>g</var> of <var>groups</var>, do<ol><li>If ! <emu-xref aoid="SameValueNonNumeric" id="_ref_7"><a href="https://tc39.es/ecma262/#sec-samevaluenonnumeric">SameValueNonNumeric</a></emu-xref>(<var>g</var>.[[Key]], <var>propertyKey</var>) is <emu-val>true</emu-val>, then<ol><li>Set <var>group</var> to <var>g</var>.</li></ol></li></ol></li><li>If <var>group</var> is <emu-const>empty</emu-const>, then<ol><li>Let <var>elements</var> be a new empty <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">List</a></emu-xref>.</li><li>Set <var>group</var> to the <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> { [[Key]]: <var>propertyKey</var>, [[Elements]]: <var>elements</var> }.</li><li>Append <var>group</var> as the last element of <var>groups</var>.</li></ol></li><li>Append <var>kValue</var> as the last element of <var>group</var>.[[Elements]].</li><li>Set <var>k</var> to <var>k</var> + 1.</li></ol></li><li>Let <var>obj</var> be ! OrdinaryObjectCreate(<emu-val>null</emu-val>).</li><li>For each <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> { [[Key]], [[Elements]] } <var>g</var> of <var>groups</var>, do<ol><li>Let <var>len</var> be the number of elements in <var>g</var>.[[Elements]].</li><li>Let <var>elements</var> be ? <emu-xref aoid="ArraySpeciesCreate" id="_ref_8"><a href="https://tc39.es/ecma262/#sec-arrayspeciescreate">ArraySpeciesCreate</a></emu-xref>(<var>O</var>, <var>len</var>).</li><li>Let <var>i</var> be 0.</li><li>For each element <var>e</var> of <var>g</var>.[[Elements]], do<ol><li>Perform ? <emu-xref aoid="CreateDataPropertyOrThrow" id="_ref_9"><a href="https://tc39.es/ecma262/#sec-createdatapropertyorthrow">CreateDataPropertyOrThrow</a></emu-xref>(<var>elements</var>, ! <emu-xref aoid="ToString" id="_ref_10"><a href="https://tc39.es/ecma262/#sec-tostring">ToString</a></emu-xref>(<emu-xref href="#𝔽"><a href="https://tc39.es/ecma262/#𝔽">𝔽</a></emu-xref>(<var>i</var>)), <var>e</var>).</li><li>Set <var>i</var> to <var>i</var> + 1.</li></ol></li><li>Perform ! <emu-xref aoid="CreateDataPropertyOrThrow" id="_ref_11"><a href="https://tc39.es/ecma262/#sec-createdatapropertyorthrow">CreateDataPropertyOrThrow</a></emu-xref>(<var>obj</var>, <var>g</var>.[[Key]], <var>elements</var>).</li></ol></li><li>Return <var>obj</var>.</li></ol></emu-alg> <emu-note><span class="note">Note 2</span><div class="note-contents"> <p>The <code>groupBy</code> function is intentionally generic; it does not require that its <emu-val>this</emu-val> value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.</p> </div></emu-note> diff --git a/spec.emu b/spec.emu index 1cf3a80..810c816 100644 --- a/spec.emu +++ b/spec.emu @@ -38,20 +38,30 @@ location: https://tc39.es/proposal-array-grouping/ 1. Let _len_ be ? LengthOfArrayLike(_O_). 1. If IsCallable(_callbackfn_) is *false*, throw a *TypeError* exception. 1. Let _k_ be 0. - 1. Let _obj_ be ! OrdinaryObjectCreate(null). - 1. Assert: _obj_ is an extensible ordinary object with no own properties. + 1. Let _groups_ be a new empty List. 1. Repeat, while _k_ < _len_ 1. Let _Pk_ be ! ToString(_k_). 1. Let _kValue_ be ? Get(_O_, _Pk_). 1. Let _propertyKey_ be ? ToPropertyKey(? Call(_callbackfn_, _thisArg_, « _kValue_, _k_, _O_ »)). - 1. Let _seen_ be ? HasOwnProperty(_obj_, _propertyKey_). - 1. If _seen_ is *true*, then - 1. Let _arr_ be ! Get(_obj_, _propertyKey_). - 1. Else - 1. Let _arr_ be ? ArraySpeciesCreate(O, 0). - 1. Perform ! CreateDataPropertyOrThrow(_obj_, _propertyKey_, _arr_). - 1. Perform ? Call(%Array.prototype.push%, _arr_, _kValue_). + 1. Let _group_ be ~empty~. + 1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do + 1. If ! SameValueNonNumeric(_g_.[[Key]], _propertyKey_) is *true*, then + 1. Set _group_ to _g_. + 1. If _group_ is ~empty~, then + 1. Let _elements_ be a new empty List. + 1. Set _group_ to the Record { [[Key]]: _propertyKey_, [[Elements]]: _elements_ }. + 1. Append _group_ as the last element of _groups_. + 1. Append _kValue_ as the last element of _group_.[[Elements]]. 1. Set _k_ to _k_ + 1. + 1. Let _obj_ be ! OrdinaryObjectCreate(*null*). + 1. For each Record { [[Key]], [[Elements]] } _g_ of _groups_, do + 1. Let _len_ be the number of elements in _g_.[[Elements]]. + 1. Let _elements_ be ? ArraySpeciesCreate(_O_, _len_). + 1. Let _i_ be 0. + 1. For each element _e_ of _g_.[[Elements]], do + 1. Perform ? CreateDataPropertyOrThrow(_elements_, ! ToString(𝔽(_i_)), _e_). + 1. Set _i_ to _i_ + 1. + 1. Perform ! CreateDataPropertyOrThrow(_obj_, _g_.[[Key]], _elements_). 1. Return _obj_. </emu-alg> <emu-note>