> Object entries() is another strange case. Iterating over Object.keys with
key=> leaves myObject[key] to access the value, whereas iterating over
Object.entries with entry=> requires entry[0] and entry[1] which seems more
verbose for access, and less readable! So do you know why this was
introduced?

Keep in mind that the pair syntax plays quite nicely with destructuring, so
assuming the iteration you're describing is something like

```
for (const key of Object.keys(myObject)) {
  const value = myObject[key];

  // do stuff
}
```

I at least think it's much more readable to do

```
for (const [key, value] of Object.entries(myObject)) {

  // do stuff
}
```

> Array entries() - it's really unclear why this would ever be used, do you
have any idea?

The same is nice for iterating arrays when you need the index

```
for (const [i, value] of ['one', 'two', 'three', 'four'].entries()) {

  // do stuff
}
```

> Imagine the mapping of an array passed into a function (or a reduce),
repeated in code for several arrays that need caching for quick access -
obviously you would expect that to be factored out into a
`toObjectByProperty` function in code, right? That's what I'm talking
about. Now imagine that transition function offered by iterable - an extra
dependency useful across multiple projects is gone. It's only nice. Isn't
it?

Generally at least for me I've transitioned to using Map objects for this
type of lookup. It's slightly longer to use `.get`, but at least for me it
hasn't been particularly troublesome. There are certainly performance
arguments to be made for polyfilled implementations, but that will only
decrease over time.


On Mon, Aug 7, 2017 at 2:41 PM, Naveen Chawla <naveen.c...@gmail.com> wrote:

> Hi Darien!
>
> Very interesting!
>
> Set.entries() is interesting - it has [value, value] with the
> justification (according to MDN) "to keep the API similar to the Map
> object".
>
> Array entries() - it's really unclear why this would ever be used, do you
> have any idea?
>
> Object entries() is another strange case. Iterating over Object.keys with
> key=> leaves myObject[key] to access the value, whereas iterating over
> Object.entries with entry=> requires entry[0] and entry[1] which seems more
> verbose for access, and less readable! So do you know why this was
> introduced?
>
> All seem motivated by Map. And I think the pattern is unhealthy, for the
> reasons given before.
>
> Sometimes we need to look at how code looks out there in production, to
> appreciate the benefits of a language feature. Imagine the mapping of an
> array passed into a function (or a reduce), repeated in code for several
> arrays that need caching for quick access - obviously you would expect that
> to be factored out into a `toObjectByProperty` function in code, right?
> That's what I'm talking about. Now imagine that transition function offered
> by iterable - an extra dependency useful across multiple projects is gone.
> It's only nice. Isn't it?
>
> On Tue, 8 Aug 2017 at 02:26 Darien Valentine <valentin...@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. (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 <valentin...@gmail.com>
>> wrote:
>>
>>> Sorry, meant to reply on-list there!
>>>
>>> On Mon, Aug 7, 2017 at 4:54 PM, Darien Valentine <valentin...@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.c...@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 <valentin...@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@mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>
>>>>>
>>>>
>>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to