Alonso
Alonso

Reputation: 43

Updating object properties and adding them in a new Arr with Reduce Javascript

I am trying to use reduce within addKeyAndValue function on an array of objects with properties of key-value pairs, add within each object a new key-value pair and return that on a new array. The addKeyAndValue func receives three arguments the arr, the key and the value to be added together within each object in the array. I then use push within Reduce callback to push the objects in the array to the new array in the accumulator with the updated new key and value using the bracket notation.

var arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}]

function addKeyAndValue(arr, key, value){
    return arr.reduce(function(acc, nextValue, idx){
        console.log(next);
        acc.push(nextValue[key] = value);
        return acc;
    },[]);
}

and the expected result should be:

addKeyAndValue(arr, 'title', 'Instructor') // 
      [
        {title: 'Instructor', name: 'Alonso'}, 
        {title: 'Instructor', name: 'James'}, 
        {title: 'Instructor', name: 'Chris'}, 
        {title: 'Instructor', name: 'Steve'}
       ]

however, the results that I get in my Chrome dev console is:

(4) ["Instructor", "Instructor", "Instructor", "Instructor"]
0:"Instructor"
1:"Instructor"
2:"Instructor"
3:"Instructor"
length:4
__proto__:Array(0)

I am wondering why is the Value passed through nextValue[key] overriding the whole object and returning just as a string. When I try to just push the existing objects in the new array it works fine but when pushing the nextValue[key] it turns undefined and when doing the above nextValue[key] = value it overrides the objects resulting into a new array with just instructor strings. I am a bit confused since I was expecting a different result.

Using the bracket notations nextValue[key] on nextValue which is each object within the array being iterated by the callback in the reduce method I thought that would add a new key property in this case "title" with the assigned value of "instructor".

Any help would be appreciated, Thanks :).

Upvotes: 0

Views: 1395

Answers (2)

Ori Drori
Ori Drori

Reputation: 192722

You are pushing the result of the assignment into the array, instead of the object.

Since the result nextValue[key] = value is value. Using acc.push(nextValue[key] = value); is like doing acc.push(value).

Since you want to update each object, use Array#map to iterate the array. Clone each object (to prevent mutating the original objects) using Object#assign, and add the property:

var arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}];

function addKeyAndValue(arr, key, value){
  return arr.map(function(obj){
    var clone = Object.assign({}, obj);
    clone[key] = value;
    return clone;
  });
}

var result = addKeyAndValue(arr, 'title', 'Instructor');

console.log(result);

The ES6 version

const arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}];

function addKeyAndValue(arr, key, value){
  return arr.map((obj) => Object.assign({ [key]: value }, obj));
}

const result = addKeyAndValue(arr, 'title', 'Instructor');

console.log(result);

Upvotes: 1

trincot
trincot

Reputation: 351084

Your push argument only results in the value being pushed, not the object. You can solve this with the comma operator if your really want this in one expression:

acc.push((nextValue[key] = value, nextValue));

But it may be more readable if you do it separately:

nextValue[key] = value;
acc.push(nextValue);

Upvotes: 2

Related Questions