Kamafeather
Kamafeather

Reputation: 9845

How to `reduce` over an object?

I wonder how to use some reduce logic over an object rather than an array. Something like iterating over tuples represented by

[ object_property, property_value ]).

I tried some code like

var obj = { foo: 'bar', bar: 'baz' };
Array.prototype.reduce.call(obj, function(prev, val) {
    console.log('new iteration');
    // whatever code ...
    return prev;
}, []);

but it doesn't perform any iteration. I can't understand why.

Maybe because the object properties are not enumerable?

Is there any way to run a reduce function on an object?

Note: There is no specific final purpose; I am exploring what's possible or what might be better patterns.

Upvotes: 0

Views: 8896

Answers (4)

Krishna Kamal
Krishna Kamal

Reputation: 771

You can use Object.keys(obj) which will give you array of property names on that array you can apply any array method(predefined) like this

var obj = { foo: 'bar', bar: 'baz' };
var prev=[] //let say prev is array in which you want to store some property value

Object.keys(obj).reduce(function(element) {
    // you can have condition here as well
    prev.push(obj[element]);
});

but be careful if you just want to populate another array then you can use other array method like filter,map,forEach(just for learning purpose because it similar to for loop) it would make sense.

Upvotes: 1

Nelson Teixeira
Nelson Teixeira

Reputation: 6572

Several mistakes.

  • obj is not an array. Use .values()
  • The result of prev.push is not the array, is the result of the push method which is 1 (integer);
  • there is no var to get the final result.

Here is a working example:

var obj = { foo: 'bar', bar: 'baz' };
var res = Array.prototype.reduce.call(Object.values(obj), function(prev, val) {
    prev.push(val);
    return prev;
}, []);
console.log(res);

I don't know why you are using Array.prototype.reduce.call. There's no need to call it this way. Maybe you're experimenting with js or something. Also prev is not a good name. Remember that it accumulates values, it's not just the previous interaction's value. Anyway, this is an easier way to do it:

var obj = { foo: 'bar', bar: 'baz' };
var res = Object.values(obj).reduce((acc, val)=>{
    acc.push(val); 
    return acc;
}, []);
console.log(res);

But if this is the answer you want, reduce is not needed at all. Look:

var obj = { foo: 'bar', bar: 'baz' };
console.log(Object.values(obj));

Upvotes: 3

Artem Skok
Artem Skok

Reputation: 180

You can run reduce() method on the array returned by Object.keys() function. It looks like this:

var obj = { foo: 'fooValue', bar: 'barValue' };
var str = Object.keys(obj).reduce((accum, key)=>{
    return accum + obj[key];
}, '');
// str = 'fooValuebarValue';

Upvotes: 1

SLaks
SLaks

Reputation: 887767

Array methods like reduce() can only operate on arrays or array-like objects (with length and numeric properties).

You can call Object.values() to get an array of an object's property values.

Upvotes: 4

Related Questions