Utkarsh Deep
Utkarsh Deep

Reputation: 37

Issue adding key value pair to javascript object from an array

I have an object like this

let obj = {
    "apple": {
    "color": "red",
  },
  "banana": {
    "color": "yellow"
  }
}

I am getting an array of objects of this form

let arr = [
  {
    "count": "9904",
    "fruit": "apple",
    "type": "typea"
  },
    {
    "count": "7142",
    "fruit": "banana",
    "type": "typeb"
  },
  {
    "count": "4121",
    "fruit": "apple",
    "type": "typec"
  }
]

I want to combine these two so that each item in objcan have variable no of properties so that final output look something like this

{
    "apple": {
    "color": "red",
    "typea": "9904",
    "typec": "4121"
  },
  "banana": {
    "color": "yellow",
    "typeb": "7142"
  }
}

I tried running the array through a for loop but when I try to use the dynamic values in keys it shows error

for (let item of arr){
    obj[item.fruit] = {...obj[item.fruit], item.type: item.count}
}

If instead of item.type I put some static value like "count" it works but I can't figure out how to use dynamic value

Can anyone suggest me what is the best way to accomplish this?

Upvotes: 1

Views: 43

Answers (2)

Cat
Cat

Reputation: 4236

Here's a verbose and explicit example of how you can do this using Array.prototype.reduce.
(Note that MDN will be down for maintenance for up to an hour at some point today.)

const
  obj = { apple:{color:"red"}, banana:{color:"yellow"} },
  arr = [
    { fruit: "apple",  type: "typeA", count: 9 },
    { fruit: "banana", type: "typeB", count: 7 },
    { fruit: "apple",  type: "typeC", count: 4 }
  ];
arr.reduce( (theObj, current) => {
  // Reduce loops through the array, updating theObj for each item
  const
    fruitName = current.fruit, // Gets fruit name
    fruitObjInObj = theObj[fruitName], // Gets fruit obj
    type = current.type, // Gets type from current item
    count = current.count; // Gets count from current item
  fruitObjInObj[type] = count; // Adds property to fruit obj
  return theObj; // Gives theObj back to `reduce` for next loop
}, obj); // Tells `reduce` to use obj as theObj on first loop

console.log(obj);

Upvotes: 0

Unmitigated
Unmitigated

Reputation: 89324

You should use computed property names with square brackets.

let obj = {
    "apple": {
    "color": "red",
  },
  "banana": {
    "color": "yellow"
  }
}
let arr = [
  {
    "count": "9904",
    "fruit": "apple",
    "type": "typea"
  },
    {
    "count": "7142",
    "fruit": "banana",
    "type": "typeb"
  },
  {
    "count": "4121",
    "fruit": "apple",
    "type": "typec"
  }
]
for (let item of arr){
    obj[item.fruit] = {...obj[item.fruit], [item.type]: item.count}
}
console.log(obj);

Upvotes: 3

Related Questions