Honestly, promoting the use of Object for this, and coupling the solution
to Array, feels like the wrong direction for the language to me personally.
By definition, such a map constructed from a set of homogenous values, for
indexing purposes, has a clear key and value type. This guidance from MDN
seems to be the right message we should be sending to developers:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

> ... ask yourself the following questions:
>
>  * Are keys usually unknown until run time? Do you need to look them up
dynamically?
>  * Do all values have the same type? Can they be used interchangeably?
>  * Do you need keys that aren't strings?
>  * Are key-value pairs frequently added or removed?
>  * Do you have an arbitrary (easily changing) number of key-value pairs?
>  * Is the collection iterated?
>
> If you answered 'yes' to any of those questions, that is a sign that you
might want to use a Map. Contrariwise, if you have a fixed number of keys,
operate on them individually, or distinguish between their usage, then you
probably want to use an Object.


On 13 August 2017 at 05:49, Naveen Chawla <naveen.c...@gmail.com> wrote:

> Verbosity.
>
> It's a task common across many project types and involves only 2
> fundamental types in ES: array and object
>
> Compare:
>
> ```
> const cache = array.reduce((cache, element)=>{cache[element.id] =
> element; return cache;}, {});
> ```
>
> with
>
> ```
> const cache = array.toObject(element=>element.id);
> ```
>
> since the signature would offer additional optional `valueFromElement` and
> `startingObject` parameters nobody loses anything.
>
> On Sun, 13 Aug 2017 at 09:51 Barret Furton <barretfur...@gmail.com> wrote:
>
>> Why not embrace `Array.prototype.reduce` instead of trying to abstract it
>> away?
>>
>> ```js
>> const identity = a => a
>>
>> const toObject = (fk, fv = identity) =>
>>     (acc, curr) => (acc[fk(curr)] = fv(curr), acc)
>>
>> const arr = [['a', '1'], ['b', '2'], ['c', '3']]
>>
>> arr.map(a => [a[0], parseInt(a[1], 10)])
>>    .filter(a => a[0] !== 'c')
>>    .reduce(toObject(a => a[0]), {}) // { a: 1, b: 2 }
>> ```
>>
>> `reduce(toObject)` clearly communicates intent, and you can even provide
>> an existing object for merging.
>>
>> On Sat, Aug 12, 2017 at 1:58 PM, Naveen Chawla <naveen.c...@gmail.com>
>> wrote:
>>
>>> My proposal was `Map.fromIterable(iterable, keyFromElement[,
>>> valueFromElement[, existingMap]])` so it's not meant to be symmetrical with
>>> `values` anyway. It was as an equivalent of `Object.fromIterable(iterable,
>>> keyFromElement[, valueFromElement[, existingObjectToUse]])` as a means to
>>> construct an object's keys and values from any iterable.
>>>
>>> I also was just thinking that both can perfectly coexist with
>>> `Array.prototype.toObject(keyFromElement[, valueFromElement])` which
>>> has the advantage of chain-ability after array transformation methods (like
>>> `filter` etc.). Array is such a fundamental construct that I would find
>>> myself using this one the most frequently
>>>
>>> On Sat, 12 Aug 2017 at 21:44 Alexander Jones <a...@weej.com> wrote:
>>>
>>>> `Map.fromIterable` takes an iterable of values, and a key function.
>>>> Would a `Map.prototype.toIterable` return only the values - that's already
>>>> `Map.prototype.values`? It feels like there is a symmetry issue here.
>>>> Perhaps this could be `Map.fromValues`?
>>>>
>>>> Worth also remembering that compressing every possible use case down to
>>>> an absolute minimum has a cost if the resultant language has too many
>>>> features like this. I think `new Map(...kvps)` is a general solution that
>>>> is actually good enough for "indexing" purposes, and means that people only
>>>> have to internalise one method of construction via iterables.
>>>>
>>>> That said, a helper function to allow constructing map-like objects
>>>> from arbitrary iterables would maybe be a bit more composable?
>>>>
>>>> ```js
>>>> // This works with Map, WeakMap, Immutable.Map, etc.
>>>> function* keyedBy(iterable, keyFn) {
>>>>   for (const element of iterable) {
>>>>     yield [keyFn(element), element];
>>>>   }
>>>> }
>>>>
>>>> const allThePeople = [{name: "Joe", age: 24}, {name: "Barbara", age:
>>>> 43}, ...];
>>>>
>>>> const index1 =
>>>>   new Map(keyedBy(allThePeople, _ => _.name));
>>>>
>>>> // c.f.
>>>> const index2 =
>>>>   Map.fromValues(allThePeople, _ => _.name);
>>>> ```
>>>>
>>>> On 11 August 2017 at 10:26, Naveen Chawla <naveen.c...@gmail.com>
>>>> wrote:
>>>>
>>>>> Of these, insertion ordering is the only one that may be compelling
>>>>> enough to me when I require that, to overcome the disadvantages. I never
>>>>> use the object prototype and I'm not convinced about the performance
>>>>> aspect. I reiterate though that `Map.fromIterable(allThePeople,
>>>>> person=>person.name)` is less verbose for the stated use case
>>>>>
>>>>> On Fri, 11 Aug 2017 at 11:55 Darien Valentine <valentin...@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> @Alexander The idea of a generalized `map` function (etc, I’m
>>>>>> guessing) is
>>>>>> appealing. From the way you talked about it, it sounds like there may
>>>>>> have been
>>>>>> past discussion on the topic. Are there any proposals for this or
>>>>>> major ideas
>>>>>> being batted around?
>>>>>>
>>>>>> > Why? What's the advantage? You lose at least the square bracket and
>>>>>> dot
>>>>>> > notations for access, as disadvantages, and I'm not aware of any
>>>>>> advantages.
>>>>>> > If there aren't any that compensate for the disadvantages, then
>>>>>> it's a net
>>>>>> > negative
>>>>>>
>>>>>> @Naveen — a handful of things. Objects are indeed a perfectly
>>>>>> reasonable choice
>>>>>> for modeling kvp collections a lot of the time. On the other hand,
>>>>>> because
>>>>>> objects in ES serve double duty as ways to model data and ways to
>>>>>> "model code",
>>>>>> they are not always ideal for the former case on account of the
>>>>>> features that
>>>>>> exist mainly to serve the second. Some examples of things that make
>>>>>> maps useful:
>>>>>> inherently iterable; no prototype chain access lookup; no collision
>>>>>> with
>>>>>> `Object.prototype` property name when hashing by arbitrary keys;
>>>>>> potentially
>>>>>> more efficient for situations where keys are frequently removed;
>>>>>> `map.has()` is
>>>>>> more straightforward than having to consider whether you want `key
>>>>>> in` or
>>>>>> `Object.hasOwnProperty` or which properties have been defined as
>>>>>> enumerable or
>>>>>> not; iteration order of entries is 1:1 with insertion order; and of
>>>>>> course, keys
>>>>>> can be of any type. Further, maps can be subclassed to constrain the
>>>>>> types that
>>>>>> they may hold or add other behaviors without needing to define custom
>>>>>> Proxies.
>>>>>>
>>>>>> Some general use cases: registries; hashing data where keys are from
>>>>>> external
>>>>>> input; kvp collections which are ordered; kvp collections which will
>>>>>> be subject
>>>>>> to later transformations; kvp collections to which new keys are
>>>>>> frequently added
>>>>>> or removed.
>>>>>>
>>>>>> While I hope that information is somewhat helpful, there are probably
>>>>>> much more
>>>>>> detailed resources online (including, I suspect, past discussions on
>>>>>> this list)
>>>>>> which could explain some of those things better or which include
>>>>>> cases I haven’t
>>>>>> thought of.
>>>>>> _______________________________________________
>>>>>> 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