Sudharsan Thevar
Sudharsan Thevar

Reputation: 43

How to dynamically assign value to same property of an object?

Let's say I have an array:

var myArr = [
    {a: {'one': 1} },
    {b: {'two': 2} },
    {a: {'three': 3} },
    {c: {'four': 4} },
    {d: {'five': 5} }
];

I want to create an Object say such that:

let myObj = {};
myObj = {
    a: {
        'one': 1,
        'three': 3
    },
    b: {'two': 2},
    c: {'four': 4},
    d: {'five': 5}
}

The property 'a' gets overridden. How to prevent this from happening?

The problem I'm facing is if i do the following:

myArr.forEach((x) => {
    myObj[Object.keys(x)[0]] = x[Object.keys(x)];
});

I get the result:

{ 
    "a": {"three": 3},
    "b": {"two": 2},
    "c": {"four": 4}, 
    "d": {"five": 5}
}

Upvotes: 4

Views: 39

Answers (2)

ibrahim mahrir
ibrahim mahrir

Reputation: 31682

You can use reduce like:

var myArr = [ {a: {'one': 1} }, {b: {'two': 2} }, {a: {'three': 3} }, {c: {'four': 4} }, {d: {'five': 5} } ];

var myObj = myArr.reduce(function(obj, o) {       // for each object o in the array myArr
  var key = Object.keys(o)[0];                    // get the key of the object o ('a', 'b', ...)
  var subKey = Object.keys(o[key])[0];            // get the key of the object inside o ('one', 'two', ...)
  if(!obj[key]) {                                 // if there is no object for the key 'key' in the result object
    obj[key] = {};                                // then add one
  }
  obj[key][subKey] = o[key][subKey];              // then add an entry for the 'subKey' to the object under the key 'key' (with the value taken from o)
  return obj;
}, {});

console.log(myObj);

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074028

You can use Object.assign within your loop for that, see comments:

var myArr = [
  {a : {'one':1}},
  {b: {'two':2}},
  {a : {'three':3}},
  {c : {'four':4}},
  {d:{'five':5}}
];

let myObj = {};
myArr.forEach(entry => {
  // Get the first key in the object
  const key = Object.keys(entry)[0];
  // Merge the object in `myObj[key]` with the one in `entry[key]`; it's okay
  // if there's no `myObj[key]`, `Object.assign` will skip over `undefined`
  myObj[key] = Object.assign({}, myObj[key], entry[key]);
});
console.log(myObj);
.as-console-wrapper {
  max-height: 100% !important;
}

That's not hyper-efficient, it recreates objects unnecessarily, but unless you're doing this in a tight loop across thousands and thousands of objects, it doesn't matter. If you are, we just branch in the iterator callback:

var myArr = [
  {a : {'one':1}},
  {b: {'two':2}},
  {a : {'three':3}},
  {c : {'four':4}},
  {d:{'five':5}}
];

let myObj = {};
myArr.forEach(entry => {
  // Get the first key in the object
  const key = Object.keys(entry)[0];
  const src = entry[key];
  const dest = myObj[key];
  if (!dest) {
    // Create a copy of the object and remember it
    myObj[key] = Object.assign({}, src);
  } else {
    // Copy properties from the source to the existing target
    Object.keys(src).forEach(k => {
      dest[k] = src[k];
    });
  }
});
console.log(myObj);
.as-console-wrapper {
  max-height: 100% !important;
}

Upvotes: 2

Related Questions