Object.values and/or Object.forEach ?

# Andrea Giammarchi (11 years ago)

it comes out from time to time devs would like to have Object.values() as equivalent of Object.keys() except the returned array would contain values.

Better than repeated Object.keys(obj).map(function(p){return this[k];}, obj); all over

but probably less useful than a more generic Object.forEach(obj, callback, thisValue) where callback would receive (value, key, originalObject) and thisValue as context.

This is consistent with Array#forEach and could simplify for/in loops passing over own enumerable properties only, as keys would do.

Thoughts ?

# Dean Landolt (11 years ago)

The for/of iterators solve this nicely. This is definitely something that comes up a lot though, and this seems like a very handy cowpath to pave. If it were spec'd I'd suggest the naming and argument values should align with the for/of variants.

# Brandon Benvie (11 years ago)

On 6/7/2013 10:18 AM, Dean Landolt wrote:

The for/of iterators solve this nicely. This is definitely something that comes up a lot though, and this seems like a very handy cowpath to pave. If it were spec'd I'd suggest the naming and argument values should align with the for/of variants.

My impression was that the @dict module solves this as you suggest.

 import { keys, values, entries } from '@dict';

 let obj = { a: 1, b: 2, c: 3 };

 for (let key of keys(obj)) {
   // ['a', 'b', 'c']
 }

 for (let value of values(obj)) {
   // [1, 2, 3]
 }

 for (let [key, value] of entries(obj)) {
   // [['a', 1], ['b', 2], ['c', 3]]
 }
# Brandon Benvie (11 years ago)

On 6/7/2013 10:18 AM, Dean Landolt wrote:

The for/of iterators solve this nicely. This is definitely something that comes up a lot though, and this seems like a very handy cowpath to pave. If it were spec'd I'd suggest the naming and argument values should align with the for/of variants.

Sorry, forgot the link. Under "Dictionaries" at harmony:modules_standard

# Dean Landolt (11 years ago)

That's what I meant by "the for/of iterators solve this nicely". I think I might have accidentally edited away the most important part of that sentence -- let me try again:

"this seems like a very handy cowpath to pave for polyfills"

This way old code can get the benefit of this painfully common idiom too (without the more heavyweight preprocessing necessary for polyfilling import syntax).

# Rick Waldron (11 years ago)

On Fri, Jun 7, 2013 at 12:57 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

it comes out from time to time devs would like to have Object.values() as equivalent of Object.keys() except the returned array would contain values.

Better than repeated Object.keys(obj).map(function(p){return this[k];}, obj); all over

but probably less useful than a more generic Object.forEach(obj, callback, thisValue) where callback would receive (value, key, originalObject) and thisValue as context.

What order would the values be in?

# Rick Waldron (11 years ago)

On Fri, Jun 7, 2013 at 1:25 PM, Brandon Benvie <bbenvie at mozilla.com> wrote:

On 6/7/2013 10:18 AM, Dean Landolt wrote:

The for/of iterators solve this nicely. This is definitely something that comes up a lot though, and this seems like a very handy cowpath to pave. If it were spec'd I'd suggest the naming and argument values should align with the for/of variants.

My impression was that the @dict module solves this as you suggest.

import { keys, values, entries } from '@dict';

let obj = { a: 1, b: 2, c: 3 };

for (let key of keys(obj)) {
  // ['a', 'b', 'c']
}

for (let value of values(obj)) {
  // [1, 2, 3]
}

for (let [key, value] of entries(obj)) {
  // [['a', 1], ['b', 2], ['c', 3]]

}

This is correct:

rwldrn/tc39-notes/blob/master/es6/2012-11/nov-29.md#conclusionresolution

# Brian Di Palma (11 years ago)

Surely the Map class would be used from now on for these use cases? It seems ideal.

# Andrea Giammarchi (11 years ago)

would this 'polyfill' as expected or there's more about these helpers ?

this['@dict'] = {
  keys: Object.keys,
  values: function(keys){
    function map(key) {
      return this[key];
    }
    return function values(obj) {
      return keys(obj).map(map, obj);
    };
  }(Object.keys),
  entries: function(keys){
    function map(key) {
      return [key, this[key]];
    }
    return function entries(obj) {
      return keys(obj).map(map, obj);
    };
  }(Object.keys)
};
# Erik Arvidsson (11 years ago)

On Fri, Jun 7, 2013 at 7:05 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

would this 'polyfill' as expected or there's more about these helpers ?

That would mostly work but these should be iterators (even though Array is iterable so your incorrect polyfill would work fine in for-of).

# Dmitry Soshnikov (11 years ago)

I might be missing something, but how for-of help solving parametrized enumeration (that is, specifying an action applied on a value/key in a functional style)?

I see clear use-case of Object.values(...) in addition to Object.keys(...), and it has nothing to do with for/of enumeration.

Why refuse a convenient library method and force users to 1) let values = []; 2) for (v of values(o)) { values.push(v); }, if it can be just let values = Object.values(o);?

Why refuse a parametrized functional iteration such as Object.forEach(o, parametrizedAction) and force users to write different static for-of loops with own loop body per each condition, if this condition can be passed as a function?

P.S.: for consistency with [].forEach, it probably would make sense having {}.forEach, but it's O.prototype pollution.

Dmitry

# Yehuda Katz (11 years ago)

Yehuda Katz (ph) 718.877.1325

On Sat, Jun 8, 2013 at 9:23 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com

wrote:

I might be missing something, but how for-of help solving parametrized enumeration (that is, specifying an action applied on a value/key in a functional style)?

I see clear use-case of Object.values(...) in addition to Object.keys(...), and it has nothing to do with for/of enumeration.

Why refuse a convenient library method and force users to 1) let values = []; 2) for (v of values(o)) { values.push(v); }, if it can be just let values = Object.values(o);?

I'm confused. Your example shows (correctly) that a values method exists that does what you want. What more are you asking for?

Why refuse a parametrized functional iteration such as Object.forEach(o, parametrizedAction) and force users to write different static for-of loops with own loop body per each condition, if this condition can be passed as a function?

I am personally in favor of a collections module that works across any iterable. I don't think we have anything on tap for ES6, but it would be trivial to write in pure JS in the ES6 timeframe and I don't see any reason it couldn't be folded in to ES7 once it gets some real-world usage.

# Axel Rauschmayer (11 years ago)

Why refuse a convenient library method and force users to

  1. let values = [];
  2. for (v of values(o)) { values.push(v); } , if it can be just let values = Object.values(o);?

Note that you can do either of the following:

let values = [...values(o)];
let values = Array.from(values(o));
# Dmitry Soshnikov (11 years ago)

On Jun 8, 2013, at 9:31 PM, Yehuda Katz wrote:

Yehuda Katz (ph) 718.877.1325

On Sat, Jun 8, 2013 at 9:23 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> wrote: I might be missing something, but how for-of help solving parametrized enumeration (that is, specifying an action applied on a value/key in a functional style)?

I see clear use-case of Object.values(...) in addition to Object.keys(...), and it has nothing to do with for/of enumeration.

Why refuse a convenient library method and force users to 1) let values = []; 2) for (v of values(o)) { values.push(v); }, if it can be just let values = Object.values(o);?

I'm confused. Your example shows (correctly) that a values method exists that does what you want. What more are you asking for?

I'm confused either (please correct me if I'm mistaken), since values(...) generator method doesn't do what I want, it returns a gen, but not an array of values corresponding to own enumerable properties (returned by Object.keys(...) with the same enumeration order).

Why refuse a parametrized functional iteration such as Object.forEach(o, parametrizedAction) and force users to write different static for-of loops with own loop body per each condition, if this condition can be passed as a function?

I am personally in favor of a collections module that works across any iterable. I don't think we have anything on tap for ES6, but it would be trivial to write in pure JS in the ES6 timeframe and I don't see any reason it couldn't be folded in to ES7 once it gets some real-world usage.

Yeah, a generic parametrized enumeration in the function style would be nice to have. As for a clear practical use-case, I don't see the reason to wait until ES7 if this may happen now:

process(o, action) { if (action == 'init') { for (let v of values(o)) { this.initValue(v); } } else if (action == 'dump') { for (let v of values(o)) { this.dumpData(v); } } else if (/* whaever */) { // how many else parametrized actions // should I apply before we have a parametrized // enumerator? } }

Which reduces basically to:

Object.forEach(o, this.init); Object.forEach(o, this.dump); // etc.

And of course everything can be implemented on a user-level, but why not to provide it out of the box?

Dmitry

# Dmitry Soshnikov (11 years ago)

On Jun 8, 2013, at 9:52 PM, Axel Rauschmayer wrote:

Why refuse a convenient library method and force users to

  1. let values = [];
  2. for (v of values(o)) { values.push(v); } , if it can be just let values = Object.values(o);?

Note that you can do either of the following:

let values = [...values(o)];
let values = Array.from(values(o));

Thanks. I though mentioned also, there is no big need to provide some alternative fancy examples of doing some action in JS. I'm pretty sure everyone on this list know/understand how the designed methods (which are discussed on this list) work and how they can be applied in alternative ways. And I also don't wanna bikeshead on how this two lines are better than Object.values(...) from the user-level perspective.

I'm not super concern about having this or that API method, but I just don't a reason not to have one if it's convenient and may help to make developers' live easier.

Anyways, cool example though, thanks for sharing.

Dmitry