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

Rewrite spec to use generic List/Records #2

Merged
merged 7 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 ?&nbsp;<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 ?&nbsp;<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 !&nbsp;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> &lt; <var>len</var><ol><li>Let <var>Pk</var> be !&nbsp;<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 ?&nbsp;<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 ?&nbsp;<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 ?&nbsp;<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 !&nbsp;<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 ?&nbsp;<emu-xref aoid="ArraySpeciesCreate" id="_ref_9"><a href="https://tc39.es/ecma262/#sec-arrayspeciescreate">ArraySpeciesCreate</a></emu-xref>(O, 0).</li><li>Perform !&nbsp;<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 ?&nbsp;<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 ?&nbsp;<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 ?&nbsp;<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> &lt; <var>len</var><ol><li>Let <var>Pk</var> be !&nbsp;<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 ?&nbsp;<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 ?&nbsp;<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 !&nbsp;<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 !&nbsp;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 ?&nbsp;<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 ?&nbsp;<emu-xref aoid="CreateDataPropertyOrThrow" id="_ref_9"><a href="https://tc39.es/ecma262/#sec-createdatapropertyorthrow">CreateDataPropertyOrThrow</a></emu-xref>(<var>elements</var>, !&nbsp;<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 !&nbsp;<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>
Expand Down
28 changes: 19 additions & 9 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -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_ &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. 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>
Expand Down