ES6 iteration over object values (original) (raw)

Does ES6 add any new ways to iterate over the values in an object? I've done a lot of searching, but haven't seen anything. I'm wondering if there is something more elegant than this:

Object.keys(myObj).forEach(function (key) {
  let obj = myObj[key];
  // do something with obj
});

Does ES6 add any new ways to iterate over the values in an object? I've done a lot of searching, but haven't seen anything. I'm wondering if there is something more elegant than this:

Object.keys(myObj).forEach(function (key) { let obj = myObj[key]; // do something with obj });

-- R. Mark Volkmann Object Computing, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140314/91651210/attachment-0001.html

Not built in, but ES6 does provide a better story for this using generators and for-of:

// using a generator function
function* entries(obj) {
   for (let key of Object.keys(obj)) {
     yield [key, obj[key]];
   }
}

// an alternative version using a generator expression
function entries(obj) {
   return (for (key of Object.keys(obj)) [key, obj[key]]);
}

for (let [key, value] of entries(myObj)) {
   // do something with key|value
}

On 3/14/2014 5:16 PM, Mark Volkmann wrote:

Does ES6 add any new ways to iterate over the values in an object? I've done a lot of searching, but haven't seen anything. I'm wondering if there is something more elegant than this:

Object.keys(myObj).forEach(function (key) { let obj = myObj[key]; // do something with obj });

Not built in, but ES6 does provide a better story for this using generators and for-of:

// using a generator function
function* entries(obj) {
   for (let key of Object.keys(obj)) {
     yield [key, obj[key]];
   }
}

// an alternative version using a generator expression
function entries(obj) {
   return (for (key of Object.keys(obj)) [key, obj[key]]);
}

for (let [key, value] of entries(myObj)) {
   // do something with key|value
}

Currently, there is no default Object.prototype.@@iterator, so for-of'ing over an object throws a TypeError which isn't really a useful default. No having a default @@iterator also makes that Map({a:1, b:2}) throws which is unfortunate.

Should what you just wrote be made the default Object.prototype.@@iterator? It is compatible with the signature the Map constructor expects too.

Le 15/03/2014 01:32, Brandon Benvie a écrit :

On 3/14/2014 5:16 PM, Mark Volkmann wrote:

Does ES6 add any new ways to iterate over the values in an object? I've done a lot of searching, but haven't seen anything. I'm wondering if there is something more elegant than this:

Object.keys(myObj).forEach(function (key) { let obj = myObj[key]; // do something with obj });

Not built in, but ES6 does provide a better story for this using generators and for-of:

// using a generator function
function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

// an alternative version using a generator expression
function entries(obj) {
  return (for (key of Object.keys(obj)) [key, obj[key]]);
}

for (let [key, value] of entries(myObj)) {
  // do something with key|value
}

Currently, there is no default Object.prototype.@@iterator, so for-of'ing over an object throws a TypeError which isn't really a useful default. No having a default @@iterator also makes that Map({a:1, b:2}) throws which is unfortunate.

Should what you just wrote be made the default Object.prototype.@@iterator? It is compatible with the signature the Map constructor expects too.

David

Le 15/03/2014 22:51, C. Scott Ananian a écrit :

It would be nicer to add an Object.entries() method that would return that iterator.

Object.prototype.entries or Object.entries(obj)?

That would be less error prone than adding a default iterator to every object.

The world has survived for-in and its weirdo unchangeable enumerable+proto-climbing rules and that was error prone. Now we can control enumerability of things that are added to the prototype and the proposed default-but-still-overridable semantics is to iterate only over own properties. It's less clear to me that the proposed semantics is error prone.

The world has also evolved to a point where tooling can be written to warn about non-overridden @@iterable property for a given "class" (I feel like it is something TypeScript could do at least).

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits. Iterable-by-default objects is a nice "battery included" feature.

Le 15/03/2014 22:51, C. Scott Ananian a écrit :

It would be nicer to add an Object.entries() method that would return that iterator.

Object.prototype.entries or Object.entries(obj)?

That would be less error prone than adding a default iterator to every object.

The world has survived for-in and its weirdo unchangeable enumerable+proto-climbing rules and that was error prone. Now we can control enumerability of things that are added to the prototype and the proposed default-but-still-overridable semantics is to iterate only over own properties. It's less clear to me that the proposed semantics is error prone.

The world has also evolved to a point where tooling can be written to warn about non-overridden @@iterable property for a given "class" (I feel like it is something TypeScript could do at least).

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits. Iterable-by-default objects is a nice "battery included" feature.

David

--scott

On Mar 15, 2014 7:42 AM, "David Bruant" <bruant.d at gmail.com <mailto:bruant.d at gmail.com>> wrote:

Le 15/03/2014 01:32, Brandon Benvie a écrit :

    On 3/14/2014 5:16 PM, Mark Volkmann wrote:

        Does ES6 add any new ways to iterate over the values in an
        object?
        I've done a lot of searching, but haven't seen anything.
        I'm wondering if there is something more elegant than this:

        Object.keys(myObj).forEach(function (key) {
          let obj = myObj[key];
          // do something with obj
        });


    Not built in, but ES6 does provide a better story for this
    using generators and for-of:

    ```js
    // using a generator function
    function* entries(obj) {
      for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
      }
    }

    // an alternative version using a generator expression
    function entries(obj) {
      return (for (key of Object.keys(obj)) [key, obj[key]]);
    }

    for (let [key, value] of entries(myObj)) {
      // do something with key|value
    }
    ```

Currently, there is no default Object.prototype.@@iterator, so
for-of'ing over an object throws a TypeError which isn't really a
useful default.
No having a default @@iterator also makes that Map({a:1, b:2})
throws which is unfortunate.

Should what you just wrote be made the default
Object.prototype.@@iterator? It is compatible with the signature
the Map constructor expects too.

David
_______________________________________________
es-discuss mailing list
es-discuss at mozilla.org <mailto: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/20140315/a394d53f/attachment.html

This thread's original question is answered by the Dict API (rwaldron/tc39-notes/blob/master/es6/2012-11/nov-29.md#conclusionresolution-5).

(more inline below)

On Sat, Mar 15, 2014 at 6:19 PM, David Bruant <bruant.d at gmail.com> wrote:

That would be less error prone than adding a default iterator to every object.

The world has survived for-in and its weirdo unchangeable enumerable+proto-climbing rules and that was error prone. Now we can control enumerability of things that are added to the prototype and the proposed default-but-still-overridable semantics is to iterate only over own properties. It's less clear to me that the proposed semantics is error prone.

The world has also evolved to a point where tooling can be written to warn about non-overridden @@iterable property for a given "class" (I feel like it is something TypeScript could do at least).

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits.

An @@iterator on Object.prototype would result in Function, Boolean, Date, Error (and friends), and RegExp, having it in their prototype chain--none of these objects have anything to produce as an iterator value.

This thread's original question is answered by the Dict API ( https://github.com/rwaldron/tc39-notes/blob/master/es6/2012-11/nov-29.md#conclusionresolution-5 ).

(more inline below)

On Sat, Mar 15, 2014 at 6:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Le 15/03/2014 22:51, C. Scott Ananian a écrit :

It would be nicer to add an Object.entries() method that would return that iterator.

Object.prototype.entries or Object.entries(obj)?

That would be less error prone than adding a default iterator to every object.

The world has survived for-in and its weirdo unchangeable enumerable+proto-climbing rules and that was error prone. Now we can control enumerability of things that are added to the prototype and the proposed default-but-still-overridable semantics is to iterate only over own properties. It's less clear to me that the proposed semantics is error prone.

The world has also evolved to a point where tooling can be written to warn about non-overridden @@iterable property for a given "class" (I feel like it is something TypeScript could do at least).

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits.

An @@iterator on Object.prototype would result in Function, Boolean, Date, Error (and friends), and RegExp, having it in their prototype chain--none of these objects have anything to produce as an iterator value.

Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140315/599148ec/attachment-0001.html

On Sat, Mar 15, 2014 at 5:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits. Iterable-by-default objects is a nice "battery included" feature.

I'm pretty sure es-discuss has been over this, but it doesn't hurt to restate:

  1. This would mean that evolving any object in any API from _not_having an @@iterator method to providing its own @@iterator method would be a backward compatibility risk. Existing code might be using the default @@iterator to enumerate the object's properties.
  2. The default Object.prototype.@@iterator would not appear on Object.create(null), so the one kind of object people would most want to have this behavior (Objects specifically created for use as dictionaries) would be the only kind of object that wouldn't have it. A separate function would be better—you could apply it to anything with properties.

Either reason alone would be enough, but to me #1 is a killer. Platform evolution hazards are bad news. You get stuff like Array.prototype.values being backed out of browsers, and then you get stuff like @@unscopables.

I'd like to see an Object.entries method, and Object.values for completeness. Same visibility rules as Object.keys.

  for (let [k, v] of Object.entries(myObj)) {
      // do something with k and v
  }

On Sat, Mar 15, 2014 at 5:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits. Iterable-by-default objects is a nice "battery included" feature.

I'm pretty sure es-discuss has been over this, but it doesn't hurt to restate:

  1. This would mean that evolving any object in any API from not having an @@iterator method to providing its own @@iterator method would be a backward compatibility risk. Existing code might be using the default @@iterator to enumerate the object's properties.

  2. The default Object.prototype.@@iterator would not appear on Object.create(null), so the one kind of object people would most want to have this behavior (Objects specifically created for use as dictionaries) would be the only kind of object that wouldn't have it. A separate function would be better—you could apply it to anything with properties.

Either reason alone would be enough, but to me #1 is a killer. Platform evolution hazards are bad news. You get stuff like Array.prototype.values being backed out of browsers, and then you get stuff like @@unscopables.

I'd like to see an Object.entries method, and Object.values for completeness. Same visibility rules as Object.keys.

for (let [k, v] of Object.entries(myObj)) { // do something with k and v }

-j

+1, or +2 counting static methods :-).

Jason Orendorff wrote:

I'd like to see an Object.entries method, and Object.values for completeness. Same visibility rules as Object.keys.

for (let [k, v] of Object.entries(myObj)) { // do something with k and v }

+1, or +2 counting static methods :-).

/be

Very enthusiastically agree--these would be excellent additions that balance nicely with Dict (null __proto__ b/w keys, values, entries), along with all of the builts-ins that received keys, values and entries on their prototypes in ES6.

On Sat, Mar 15, 2014 at 7:38 PM, Jason Orendorff <jason.orendorff at gmail.com>wrote:

On Sat, Mar 15, 2014 at 5:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Even if error prone, I'd be interested to hear about arguments in the sense that the risk outweighs the benefits. Iterable-by-default objects is a nice "battery included" feature.

I'm pretty sure es-discuss has been over this, but it doesn't hurt to restate:

  1. This would mean that evolving any object in any API from not having an @@iterator method to providing its own @@iterator method would be a backward compatibility risk. Existing code might be using the default @@iterator to enumerate the object's properties.

  2. The default Object.prototype.@@iterator would not appear on Object.create(null), so the one kind of object people would most want to have this behavior (Objects specifically created for use as dictionaries) would be the only kind of object that wouldn't have it. A separate function would be better--you could apply it to anything with properties.

Either reason alone would be enough, but to me #1 is a killer. Platform evolution hazards are bad news. You get stuff like Array.prototype.values being backed out of browsers, and then you get stuff like @@unscopables.

I'd like to see an Object.entries method, and Object.values for completeness. Same visibility rules as Object.keys.

for (let [k, v] of Object.entries(myObj)) { // do something with k and v }

Very enthusiastically agree--these would be excellent additions that balance nicely with Dict (null _proto b/w keys, values, entries), along with all of the builts-ins that received keys, values and entries on their prototypes in ES6.

Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140315/0742033d/attachment.html

On Sat, Mar 15, 2014 at 6:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Le 15/03/2014 22:51, C. Scott Ananian a écrit : It would be nicer to add an Object.entries() method that would return that iterator.

Object.prototype.entries or Object.entries(obj)?

Object.entries(obj) and Object.values(obj) (as suggested by Jason).

The linked resolution for Dict(rwaldron/tc39-notes/blob/master/es6/2012-11/nov-29.md#conclusionresolution-5) was less than clear, but generic Dict.keys(obj),Dict.entries(obj), and Dict.values(obj) which can take arbitrary objects (not just objects with no prototype) would be an okay fallback. It leaves Object.keys an orphan, alas.Dict.prototype.entries.call(obj) would be too long to be useful (but I don't think that was being proposed).

for (let [key, value] of Dict.entries(myObj)) {
   // do something with key|value
}

That's not too bad. Shorter than Object.entries, even. (But I personally don't see the point of new Dict() instead ofObject.create(null), and prefer the Object.* names.)

On Sat, Mar 15, 2014 at 6:19 PM, David Bruant <bruant.d at gmail.com> wrote:

Le 15/03/2014 22:51, C. Scott Ananian a écrit : It would be nicer to add an Object.entries() method that would return that iterator.

Object.prototype.entries or Object.entries(obj)?

Object.entries(obj) and Object.values(obj) (as suggested by Jason).

The linked resolution for Dict (https://github.com/rwaldron/tc39-notes/blob/master/es6/2012-11/nov-29.md#conclusionresolution-5) was less than clear, but generic Dict.keys(obj), Dict.entries(obj), and Dict.values(obj) which can take arbitrary objects (not just objects with no prototype) would be an okay fallback. It leaves Object.keys an orphan, alas. Dict.prototype.entries.call(obj) would be too long to be useful (but I don't think that was being proposed).

for (let [key, value] of Dict.entries(myObj)) {
   // do something with key|value
}

That's not too bad. Shorter than Object.entries, even. (But I personally don't see the point of new Dict() instead of Object.create(null), and prefer the Object.* names.) --scott

Alright, convinced too.

Thanks :-)

Le 16/03/2014 00:45, Rick Waldron a écrit :

On Sat, Mar 15, 2014 at 7:38 PM, Jason Orendorff <jason.orendorff at gmail.com <mailto:jason.orendorff at gmail.com>> wrote:

On Sat, Mar 15, 2014 at 5:19 PM, David Bruant <bruant.d at gmail.com
<mailto:bruant.d at gmail.com>> wrote:
> Even if error prone, I'd be interested to hear about arguments
in the sense
> that the risk outweighs the benefits. Iterable-by-default
objects is a nice
> "battery included" feature.

I'm pretty sure es-discuss has been over this, but it doesn't hurt
to restate:

1. This would mean that evolving any object in any API from *not*
having an @@iterator method to providing its own @@iterator method
would be a backward compatibility risk. Existing code might be using
the default @@iterator to enumerate the object's properties.

2. The default Object.prototype.@@iterator would not appear on
Object.create(null), so the one kind of object people would most want
to have this behavior (Objects specifically created for use as
dictionaries) would be the only kind of object that wouldn't have it.
A separate function would be better---you could apply it to anything
with properties.

Either reason alone would be enough, but to me #1 is a killer.
Platform evolution hazards are bad news. You get stuff like
Array.prototype.values being backed out of browsers, and then you get
stuff like @@unscopables.

I'd like to see an Object.entries method, and Object.values for
completeness. Same visibility rules as Object.keys.

  for (let [k, v] of Object.entries(myObj)) {
      // do something with k and v
  }

Very enthusiastically agree---these would be excellent additions that balance nicely with Dict (null _proto b/w keys, values, entries), along with all of the builts-ins that received keys, values and entries on their prototypes in ES6. Alright, convinced too.

Thanks :-)

David -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140316/7de5a88e/attachment.html

What happened to adding the Object.values and Object.entries methods? There was some discussion that led me to believe these would be in ES6. Are they now targeted for ES7?

What happened to adding the Object.values and Object.entries methods? There was some discussion that led me to believe these would be in ES6. Are they now targeted for ES7?

-- R. Mark Volkmann Object Computing, Inc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140928/b0a2b4c7/attachment.html

On Sun, Sep 28, 2014 at 11:28 AM, Mark Volkmann <r.mark.volkmann at gmail.com> wrote:

What happened to adding the Object.values and Object.entries methods? There was some discussion that led me to believe these would be in ES6. Are they now targeted for ES7?

Yes, proposed by me and always for ES7 https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-04/apr-9.md#51-objectentries-objectvalues I will complete the necessary tasks for Stage 1 at next meeting.

Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140928/a2c9cde5/attachment.html

Returning just arrays will be inconsistent with the same name methods that sit on prototypes of Array, Map, etc.

Yes, Object.keys(...) poisons the iterators idea, but I think these better to be iterators.

Or, if Object.values and Object.entries will start returning simple arrays (which of cours is consistent with Object.keys), then probably the iterator method names are better to rename. (Object.keysIterator(), or something, don't know yet -- verbose, but does what it says)

Anyhow, since it's ES7, there's a plenty of time to discuss.

Returning just arrays will be inconsistent with the same name methods that sit on prototypes of Array, Map, etc.

Yes, Object.keys(...) poisons the iterators idea, but I think these better to be iterators.

Or, if Object.values and Object.entries will start returning simple arrays (which of cours is consistent with Object.keys), then probably the iterator method names are better to rename. (Object.keysIterator(), or something, don't know yet -- verbose, but does what it says)

Anyhow, since it's ES7, there's a plenty of time to discuss.

Dmitry

On Sunday, September 28, 2014, Rick Waldron <waldron.rick at gmail.com> wrote:

On Sun, Sep 28, 2014 at 11:28 AM, Mark Volkmann <r.mark.volkmann at gmail.com <javascript:_e(%7B%7D,'cvml','r.mark.volkmann at gmail.com');>> wrote:

What happened to adding the Object.values and Object.entries methods? There was some discussion that led me to believe these would be in ES6. Are they now targeted for ES7?

Yes, proposed by me and always for ES7 https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-04/apr-9.md#51-objectentries-objectvalues I will complete the necessary tasks for Stage 1 at next meeting.

Rick

-------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20140928/0fa379cb/attachment.html