Array.prototype.toObjectByProperty( element=>element.property )
Darien Valentine
valentinium at gmail.com
Mon Aug 7 20:56:19 UTC 2017
> The concept of using a 2-element array to represent a key and value is
unique to Maps
The entries pattern is not unique to `Map` — it’s also used by
`Object.entries`, `Set.entries`, and `Array.entries` — e.g.
for (const [ index, member ] of array.entries()) ...
A bit tangential, but in the case of `Map`, it’s perhaps notable that the
contract for "entry" is not "an array of two and only two members". It is
"any object at all", with the implied expectation that you’d want
properties keyed by "0" and "1" defined on it in order for it to be useful.
Regardless of one’s thoughts on `Map` (which I use quite a bit personally),
the "entries" pattern is well established in ES. (I’d also point out that
adding a method for composition from entries does not preclude supporting
other approaches.)
On Mon, Aug 7, 2017 at 4:54 PM, Darien Valentine <valentinium at gmail.com>
wrote:
> Sorry, meant to reply on-list there!
>
> On Mon, Aug 7, 2017 at 4:54 PM, Darien Valentine <valentinium at gmail.com>
> wrote:
>
>> > The concept of using a 2-element array to represent a key and value is
>> unique to Maps
>>
>> The entries pattern is not unique to `Map` — it’s also used by
>> `Object.entries`, `Set.entries`, and `Array.entries` — e.g.
>>
>> for (const [ index, member ] of array.entries()) ...
>>
>> A bit tangential, but in the case of `Map`, it’s perhaps notable that the
>> contract for "entry" is not "an array of two and only two members". It is
>> "any object at all", with the implied expectation that you’d want
>> properties keyed by "0" and "1" defined on it in order for it to be useful.
>>
>> Regardless of one’s thoughts on `Map` (which I use quite a bit
>> personally), the "entries" pattern is well established in ES.
>>
>>
>>
>> On Mon, Aug 7, 2017 at 3:24 PM, Naveen Chawla <naveen.chwl at gmail.com>
>> wrote:
>>
>>> Hi Darien!
>>>
>>> The concept of using a 2-element array to represent a key and value is
>>> unique to Maps and if I'm not mistaken, exists purely because there wasn't
>>> a tight, compact alternative that could house a key and value where the key
>>> could be an object.
>>>
>>> However, if we are going straight from iterable to Object, I don't think
>>> we should be propagating the "[key, value] as an array" pattern. It's
>>> unclean partly because it's 2 elements max and IDEs can't inherently show
>>> warnings if you accidentally added more, unless it has some intelligence
>>> about the method itself. Partly also because the arrays are not immediately
>>> readable unless you already know the that the arrays mean [key, value].
>>>
>>> I'm not convinced that Maps have any real value at all right now vs
>>> objects (despite what the documentation says): currently they only offer
>>> the ability to have objects as keys but without custom key equality (only
>>> ===), and you lose the elegant square bracket syntax for accessing
>>> elements, among other things, so it's unclear to me how compelling the use
>>> of Maps vs objects is at all in real world scenarios, so I'm not sure
>>> anything about Maps should be a pattern for other language features.
>>>
>>> Iterables are very generic, since they can include generators, sets etc.
>>> Objects are a fundamental construct, so it makes sense to be able to
>>> cleanly transition between these structures.
>>>
>>> Adding the idea to iterable in general (instead of just Array) would
>>> look like e.g.:
>>>
>>> ```
>>> const cache = iterable.toObjectByProperty(item=>item.id)
>>> ```
>>>
>>> On Sun, 6 Aug 2017 at 02:12 Darien Valentine <valentinium at gmail.com>
>>> wrote:
>>>
>>>> FWIW, while I find needs like this common, too, where Map is sensible
>>>> instead of
>>>> Object, it does come out pretty clean:
>>>>
>>>> ```
>>>> const a = [
>>>> {id: "tjc", name: "T.J. Crowder"},
>>>> {id: "nc", name: "Naveen Chawla"},
>>>> {id: "lh", name: "Lachlan Hunt"}
>>>> ];
>>>>
>>>> const index = new Map(a.map(member => [ member.name, member ]));
>>>> ```
>>>>
>>>> Although I’m also puzzled by the suggestion that reducing to an object
>>>> is an abuse,
>>>> I do find I wish there were a complement to `Object.entries`:
>>>>
>>>> ```
>>>> // Object to pairs, and therefore map, is simple:
>>>>
>>>> const map = new Map(Object.entries(obj));
>>>>
>>>> // Converting back is also simple ... but not exactly expressive:
>>>>
>>>> [ ...map ].reduce((acc, [ key, val ]) => Object.assign(acc, { [key]:
>>>> val }));
>>>> ```
>>>>
>>>> Something like `Object.fromEntries` would not provide as much sugar for
>>>> the
>>>> OP case as `toObjectByProperty`, but it gets pretty close and has the
>>>> advantage
>>>> of being more generic; `toObjectByProperty` strikes me as rather
>>>> specific for a
>>>> built-in, especially since one might want to map by a derived value
>>>> rather than
>>>> a property. Both map<->object and array<->object cases would become more
>>>> expressive — plus it follows pretty naturally from the existence of
>>>> `Object.entries` that there might be a reverse op.
>>>>
>>>> ```
>>>> Object.fromEntries(a.map(a.map(member => [ member.name, member ])));
>>>> ```
>>>>
>>>> In other words, `Object.fromEntries(Object.entries(obj))` would be
>>>> equivalent in
>>>> effect to `Object.assign({}, obj)`.
>>>>
>>>> Would that adequately address this case you think? My sense is that
>>>> it’s better to supply generic helpers before more specific helpers when it
>>>> comes to built-ins.
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170807/7ecf6998/attachment-0001.html>
More information about the es-discuss
mailing list