As far as I remember Maps have the same performance as objects in case of
dynamic property access for small collections and better for big ones (I
have value of 255 in my mind, but I can't test it now). And objects do
maintain insert order, at least in some cases.
On Tue, 15 Aug 2017 at 23:45, Nav
OK, I have written up a proposal that I really hope satisfies every single
requirement outlined in this discussion. If not, please recommend
amendments. It is here:
https://github.com/TheNavigateur/arrays-and-other-iterables-to-objects-and-maps
.
Do give comments here either way
On Mon, 14 Aug 201
On Mon, Aug 14, 2017 at 7:33 AM, Naveen Chawla
wrote:
> I've never been concerned about needing to allow "toString" etc.
> as valid cache keys, so it's never been an issue for me so far.
> However, if I did in future, I would honestly look to delete them
> from the Object.prototype in my applicati
For iteration, `Object.keys()` doesn't include any property in the
prototype chain like "toString" etc.
I've never been concerned about needing to allow "toString" etc. as valid
cache keys, so it's never been an issue for me so far. However, if I did in
future, I would honestly look to delete them
> is nearly always a perfect fit for this
The fact that it is so close to being useful, but has silly surprises like
`'toString' in everyObject`, actually gives JS a bad reputation and
contributes towards people being driven to other languages that have
cleaner approaches to data types.
On 13 Aug
Object self-promotes because it is nearly always a perfect fit for this:
great performance, great literal syntax, concise access syntax. The only
compelling case to use a map instead is when insertion ordering is
required, despite the MDN article. I wouldn't oppose an equivalent
`Array.prototype.to
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
For the same reason why we have filter, forEach, map etc.
Reduce is actually rather low level primitive (if we can call functional
concept low level) and specialised methods should be preferred over it's
usage if possible.
On 13 Aug 2017 6:21 am, "Barret Furton" wrote:
> Why not embrace `Array.p
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);
```
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)])
.
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
`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
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
@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 lea
On Thu, Aug 10, 2017 at 11:24 PM, Alexander Jones wrote:
>
> As far as I'm concerned, "most data arrays" — at least the ones
> you're speaking about — should actually be `Map`s.
I see the point you're trying to make, but
1. I routinely want paging and other access by arbitrary index
2. I routin
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
On Fri, 11 Aug 2017 at 09:41 Naveen Chawla wrote:
> `Map.fromIterable(allThePeople, person
`Map.fromIterable(allThePeople, person=>person.name)` is less verbose for
your use case
On Fri, 11 Aug 2017 at 03:54 Alexander Jones wrote:
> As far as I'm concerned, "most data arrays" — at least the ones you're
> speaking about — should actually be `Map`s.
>
Why? What's the advantage?
___
As far as I'm concerned, "most data arrays" — at least the ones you're
speaking about — should actually be `Map`s. And their iterators (from, and
to) yield key-value pairs. There is no syntax for a strict pair, so
2-element arrays have to do.
I'd still rather see some approach to generator express
I've yet to see any demonstration code use case for a `fromEntries` where
it would ever be preferable over a `fromIterable`, seeing as most back end
API JSON data arrays, and most data arrays in general for that matter, do
not come in the form of "entries". I would suggest that a `fromIterable`
wit
On Thu, Aug 10, 2017 at 9:49 AM, Naveen Chawla
wrote:
>
> I think a property value callback is needed for completeness (not
> easy to achieve the same functionality without it.
In my view, a Swiss Army knife is not a good API function. (These are
always, of course, judgement calls.) The `[key, va
I think a property value callback is needed for completeness (not easy to
achieve the same functionality without it. Consider the examples given in
the recent posts).
Keying by a string property name should, in my view, be a separate function:
```
Object.fromIterableByPropertyName(iterable, prope
By "much more generic" I mean that `fromIterable` more effortlessly fits a
much wider range of use cases.
Can you give a code example of where your entries originate from? I'm
curious because you might find it easier to apply `fromIterable` (since
most server side API data arrays don't come in the
On Wed, Aug 9, 2017 at 10:56 PM, Jordan Harband wrote:
>
> TJ:
> I'm confused, can you provide a code sample?
So based on the signatures I mentioned [here][1]:
```js
Object.from(iterable, indexer, target = Object.create(null))
// and
Map.from(iterable, indexer, target = new Map)
```
(although `
"Generic" can't apply when constructing an object, since you always need
pairs of a key and a value - so it doesn't need to be generic; it needs to
fit the use case.
Yes, I've had many a need for "fromEntries" or similar, which I've usually
achieved with a reduce. I've never once needed to create
`fromEntries` is much less generic than `fromIterable` (since not every
iterable is an entries, but every entries is an iterable) and is much more
verbose to use in the use cases we have just discussed. I have faced such
cases often, but have NEVER faced a need for a `fromEntries`. Have you?
Even i
Naveen:
`Object.fromIterable(recentCountryNames, countryName=>countryName,
countryName=>countriesByName[countryName])`
could also be:
`Object.fromEntries(Array.from(recentCountryNames, countryName =>
([countryName, countriesByName[countryName]])))`, without needing a
potentially confusing "keyCal
Hi Jordan, great question.
An iterable of anything!
This is the signature:
```
Object.fromIterable(iterable, keyFromElement[, valueFromElement])
```
Examples follow:
Supposing you had an array:
```
[
{
countryName: 'UK',
population: 6564
},
{
countryNam
On Wed, Aug 9, 2017 at 9:24 AM, Jordan Harband wrote:
>
> I think you're misunderstanding; the function would of course take
> an iterable. However, an iterable of what?
>
> If it's an iterable of objects, then what's the key and what's the
> value? What if it's an iterable of strings?
I can't sp
I think you're misunderstanding; the function would of course take an
iterable. However, an iterable of what?
If it's an iterable of objects, then what's the key and what's the value?
What if it's an iterable of strings?
The only thing that makes sense is if it's an iterable that provides both a
It is more generic than `fromEntries`
On Wed, 9 Aug 2017 at 13:32 Naveen Chawla wrote:
> Iterable to object via `Object.fromIterable`
>
> On Wed, 9 Aug 2017 at 13:31 Jordan Harband wrote:
>
>> JS doesn't have interfaces (yet, tho there's a proposal) and regardless,
>> the "interface" for "itera
Iterable to object via `Object.fromIterable`
On Wed, 9 Aug 2017 at 13:31 Jordan Harband wrote:
> JS doesn't have interfaces (yet, tho there's a proposal) and regardless,
> the "interface" for "iterable" is "it has Symbol.iterator, nothing more".
>
> The only place a method like this - that produ
JS doesn't have interfaces (yet, tho there's a proposal) and regardless,
the "interface" for "iterable" is "it has Symbol.iterator, nothing more".
The only place a method like this - that produces an object - could
possibly exist, is a static method on Object.
I've already outlined two existing m
But I accept that this a very tall order for ES
On Wed, 9 Aug 2017 at 13:22 Naveen Chawla wrote:
> Java has a great example of such a construct: default interface methods
>
> On Wed, 9 Aug 2017 at 13:21 Naveen Chawla wrote:
>
>> The `toObject` behaviour doesn't need to be "implemented" on a
>>
Java has a great example of such a construct: default interface methods
On Wed, 9 Aug 2017 at 13:21 Naveen Chawla wrote:
> The `toObject` behaviour doesn't need to be "implemented" on a
> per-iterable class basis. It has a constant behaviour: iterate and on each
> next(), pass the value to the `
The `toObject` behaviour doesn't need to be "implemented" on a per-iterable
class basis. It has a constant behaviour: iterate and on each next(), pass
the value to the `toKeyFromElement` and `toValueFromElement` callbacks to
generate and return an object. There must be some construct by which that
Something is iterable if it has `Symbol.iterator`. Are you saying that
every iterable would then need to add a `toObject` method? What happens if
it doesn't add it? What value is it if most iterables don't have `toObject`
but only some do?
On Wed, Aug 9, 2017 at 12:40 AM, Naveen Chawla
wrote:
>
On Wed, Aug 9, 2017 at 8:35 AM, Naveen Chawla wrote:
>
> It would be in the `iteratable` `protocol` (interface)
As Jordan said, that's likely to be a nonstarter. The Iterable protocol is
*very* lean (exactly one required property) for a reason: So it can be
supported with minimum investment. Much
`iterable`, excuse me
On Wed, 9 Aug 2017 at 13:05 Naveen Chawla wrote:
> It would be in the `iteratable` `protocol` (interface)
>
> On Wed, 9 Aug 2017 at 13:03 Naveen Chawla wrote:
>
>> You're thinking of `iterator`
>>
>> On Wed, 9 Aug 2017 at 13:01 Jordan Harband wrote:
>>
>>> An iterator is
It would be in the `iteratable` `protocol` (interface)
On Wed, 9 Aug 2017 at 13:03 Naveen Chawla wrote:
> You're thinking of `iterator`
>
> On Wed, 9 Aug 2017 at 13:01 Jordan Harband wrote:
>
>> An iterator is just an object with a `next` method. There's no consistent
>> place to put any protot
You're thinking of `iterator`
On Wed, 9 Aug 2017 at 13:01 Jordan Harband wrote:
> An iterator is just an object with a `next` method. There's no consistent
> place to put any prototype methods on all iterables, so that's a nonstarter
> imo.
>
> On Wed, Aug 9, 2017 at 12:26 AM, Naveen Chawla
> w
An iterator is just an object with a `next` method. There's no consistent
place to put any prototype methods on all iterables, so that's a nonstarter
imo.
On Wed, Aug 9, 2017 at 12:26 AM, Naveen Chawla
wrote:
> I do not use entries so I would not use `Object.fromEntries`. For arrays I
> could ju
I do not use entries so I would not use `Object.fromEntries`. For arrays I
could just use reduce, instead of transforming to [key, value] entries,
before factoring it into an `arrayToObject` function in my code (which I
already do) when I want to do it from more than one place in my code - if
there
OK thanks for the link - can you explain where the complexity is in my
proposal?
On Tue, 8 Aug 2017 at 16:14 T.J. Crowder
wrote:
> On Tue, Aug 8, 2017 at 11:39 AM, Naveen Chawla
> wrote:
> > Furthermore, if you use entries, this allows `[key, value]` entries
> > with object keys to be transform
On Tue, Aug 8, 2017 at 11:39 AM, Naveen Chawla
wrote:
> Furthermore, if you use entries, this allows `[key, value]` entries
> with object keys to be transformed into objects (which is not
> allowed by `Object.fromEntries`):
With respect, please do have a *thorough* read of my first reply in this
Furthermore, if you use entries, this allows `[key, value]` entries with
object keys to be transformed into objects (which is not allowed by
`Object.fromEntries`):
```
const cache = entries.toObject(entry=>entry[0].type, entry=>entry[1]);
```
On Tue, 8 Aug 2017 at 15:52 Naveen Chawla wrote:
> P
Philosophically I agree completely with this principle.
This does not have a bunch of options:
```
iterable.toObject(keyFromElement[, valueFromElement])
```
What I proposed has only 1 variant: the fact that `valueFromElement` has a
default if you don't provide it.
Objects as they are are simple
On Tue, Aug 8, 2017 at 10:01 AM, Naveen Chawla
wrote:
>
> Yeah except in what I'm saying it's optional
My point is you'd use the right tool for the job at hand, rather than
having a single tool with a bunch of options making it complex to explain,
use, and optimize. If you review my earlier sugge
Yeah except in what I'm saying it's optional
On Tue, 8 Aug 2017 at 14:16 T.J. Crowder
wrote:
> On Tue, Aug 8, 2017 at 9:39 AM, Naveen Chawla
> wrote:
> > I'd like to propose an enhancement to my proposal:
> > ...
> > It offers the same functionality, but in addition a second
> > optional parame
On Tue, Aug 8, 2017 at 9:39 AM, Naveen Chawla wrote:
> I'd like to propose an enhancement to my proposal:
> ...
> It offers the same functionality, but in addition a second
> optional parameter for the "value" in case you want something
> other than the array element as the value. By default, if t
I'd like to propose an enhancement to my proposal:
```
const cache = iterable.toObject(item=>item.key, item=>item); //2nd param is
optional, default shown
```
It offers the same functionality, but in addition a second optional
parameter for the "value" in case you want something other than the ar
On Tue, Aug 8, 2017 at 7:18 AM, Naveen Chawla wrote:
> It'd be great to know if anyone from TC39 is going to propose these
> ideas (could I submit a README.md in order to help? If so where?)
Proposals come from the community (of which TC39 members are a part). What
you've done so far is a suggest
Another benefit of iterable toObjectByProperty(element=>element.id) is that
it can be placed at the end of a transformation chain of `map` `sort`
`filter` `concat` etc.:
```
const
cache =
sourceIterable
.filter(item=>item.isValid)
.toObjectByProperty(item=>item.i
> I haven't seen any suggestions for anything different than those three
patterns; am I missing something?
The draft I assembled does follow that pattern, but there was [another
approach suggested](https://esdiscuss.org/topic/array-prototype-
toobjectbyproperty-element-element-property#content-2)
If you have an object, you can already `Object.assign({}, object)`, or
`Object.defineProperties({}, Object.getOwnPropertyDescriptors(object))`,
with no intermediary, as of ES2015 and ES2017 respectively.
The value here for something new would be
`Object.fromEntries(Object.entries(object).map(…).fi
> forced into it as an intermediary
Fortunately, no force is involved :)
T.J. Crowder indicated an intention to draft a proposal that I believe
aligns
with your ideas for converting objects to a single object by key with an
all-in-one map+compose method. It is not necessary for there to be only a
On Tue, 8 Aug 2017 at 03:28 Logan Smyth wrote:
> > 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,
On Tue, 8 Aug 2017 at 03:25 Jordan Harband wrote:
> Entries are an established pattern. Relitigating it isn't going to be
> useful. Something like this would only make sense if it accepted either an
> iterable of entries, or an array of entries (which is strictly less useful
> than taking an iter
> 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
introduce
Entries are an established pattern. Relitigating it isn't going to be
useful. Something like this would only make sense if it accepted either an
iterable of entries, or an array of entries (which is strictly less useful
than taking an iterable) - no other input value would make sense to me.
On Mon
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 c
> 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
On Mon, Aug 7, 2017 at 10:24 PM, Naveen Chawla
wrote:
> 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.
>
Consistency is good, and especially better than for example adding new
syntax. Subjectively not a
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 itera
On Mon, Aug 7, 2017 at 4:17 PM, Darien Valentine
wrote:
>
> > Where are you thinking of? [re: other methods that could take
overloaded/shorthand map/predicate args, but do not]
>
> These could also accept strings for property mapping in the same manner
you proposed, but do not currently:
>
> - `Ar
> Where are you thinking of? [re: other methods that could take
overloaded/shorthand map/predicate args, but do not]
These could also accept strings for property mapping in the same manner you
proposed, but do not currently:
- `Array.from`
- `Array.prototype.every`
- `Array.prototype.filter`
- `A
On Mon, Aug 7, 2017 at 2:23 PM, Darien Valentine
wrote:
> > For me, no; an unnecessary additional transform and too much.
> > memory churn.
>
> However I suspect the idea of accepting a string or symbol key
> rather than a function is unlikely to gain traction — for one,
> there’s nothing like it
> For me, no; an unnecessary additional transform and too much memory churn.
Interesting. I’ve included a note in the 'concerns' section on that
proposal regarding the possibility of accepting a mapping function (like
`Array.from`). That could avoid the extra array creation. However I suspect
the
On Sat, Aug 5, 2017 at 9:42 PM, Darien Valentine
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", n
Awesome. I didn’t know about the upcoming template, so I may have jumped
the gun haha:
https://github.com/bathos/object-from-entries
It’s quite primitive though, no formal algorithm / ecmarkup or anything.
I’ll keep an eye on the template project and update accordingly once that’s
ready, thanks.
@Isiah I think you and I just described the identical thing (except that
I’d put `fromEntries` where you put `from`) — and it’s a subset of the
overloaded proposed solution from Crowder above. That three people
responded with the same thing or a variation of it suggests that this is
indeed a gap wh
If anything *were* to be added, it would surely be a static method that
took an iterable of entries and returned an object, and it would surely
have the semantic that `new Set(Object.entries(thisThing(entries)))` and
`new Set(entries)` were two conceptually equal sets (iow, that each
corresponding
I have a better idea: how about `Object.from(iter)`, where `iter` is
an iterable of `[key, value]` pairs?
```
const a = [
{id: "tjc", name: "T.J. Crowder"},
{id: "nc", name: "Naveen Chawla"},
{id: "lh", name: "Lachlan Hunt"}
];
const object = Object.from(a.map(o => [o.id, o.name]))
```
We
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.na
73 matches
Mail list logo