user3486427
user3486427

Reputation: 474

Loop through an array of objects and create a new object

I have an array of objects, each object has a title, content and contentHTML. I want to map over this array and create a new object. The new object will take the value of the title property and use this as the parent property for each of the content and contentHTML properties. The code below only seems to be getting the last object in the array.

The results is:

{
  "sidebar": {
      "text": "Some sidbar text here",
      "content": "<p>Some sidebar text here</p>"
    }
}

The expected result is:

{
    header: {
        text: "Some header text here",
        content: "<p>Some header text here</p>"
    },
    footer: {
        text: "Some footer text here",
        content: "<p>Some footer text here</p>"
    },
    sidebar: {
        text: "Some sidbar text here",
        content: "<p>Some sidebar text here</p>"
    }
}

var originalObj = [{
    title: "header",
    content: "Some header text here",
    contentHTML: "<p>Some header text here</p>"
  },
  {
    title: "footer",
    content: "Some footer text here",
    contentHTML: "<p>Some footer text here</p>"
  },
  {
    title: "sidebar",
    content: "Some sidbar text here",
    contentHTML: "<p>Some sidebar text here</p>"
  }
];
let newObject = {};
for (let item of originalObj) {
  var tempObj = {
    [item.title]: {
      text: item.content,
      content: item.contentHTML
    }
  };
  newObject = tempObj;
}
console.log(newObject);

Upvotes: 3

Views: 4934

Answers (6)

Aravind Kethireddy
Aravind Kethireddy

Reputation: 23

I tried with a different example and wanted to answer more dynamically firstly, getting how many unique values we can have for a property i.e,res array in this example then, filtering the objects and pushing into an array that the object's property matches with each unique value of the res array in the example the resultant object is resObj

let anArray = [{id: 1, name:"orange"},
{id: 2, name:"orange"},
{id: 3, name:"apple"},
{id: 4, name:"apple"},
{id: 5, name:"rusk"},
{id: 6, name:"grape"}]
let res =  [...new Set(anArray.map(item => item.name))];
let resObj = {};

let newObj = (item, arr) => {
    let resArr = [];
  
    anArray.map((obj) => {
     if(item == obj.name){
     resArr.push(obj)
     }
 })
 return resArr
}
resObject = Object.fromEntries(res.map((item) => [item, newObj(item, anArray) ]) )

 
console.log(resObject)

Upvotes: 0

Anurag Awasthi
Anurag Awasthi

Reputation: 6223

You are overwriting your object with new value every time you're doing

var tempObj = {//object keys}

Use spread operator to copy the previous values. Spread operator loops through objects iterable values and expands them.

var originalObj = [
    {
        title: "header",
        content: "Some header text here",
        contentHTML: "<p>Some header text here</p>"
    },
    {
        title: "footer",
        content: "Some footer text here",
        contentHTML: "<p>Some footer text here</p>"
    },
    {
        title: "sidebar",
        content: "Some sidbar text here",
        contentHTML: "<p>Some sidebar text here</p>"
    }
];

let newObject = {};
for (let item of originalObj) {
    newObject = {
        ...newObject,
        [item.title]: {
            text: item.content,
            content: item.contentHTML
        }
    };
}
console.log(newObject);

Upvotes: 3

ddy250
ddy250

Reputation: 311

It has been answered but if it still helps:

var newObject = {};
for (let item of originalObj) {
      newObject[item.title] = {
      text: item.content,
      content: item.contentHTML
    }
  };

Upvotes: 0

Ele
Ele

Reputation: 33726

This alternative uses the function reduce to build the desired output.

var originalObj = [	{		title: "header",		content: "Some header text here",		contentHTML: "<p>Some header text here</p>"	},	{		title: "footer",		content: "Some footer text here",		contentHTML: "<p>Some footer text here</p>"	},	{		title: "sidebar",		content: "Some sidbar text here",		contentHTML: "<p>Some sidebar text here</p>"	}],
    newObject = originalObj.reduce((a, {title, content: text, contentHTML: content} = obj) => {
      return Object.assign(a, {[title]: {text, content}});
    }, Object.create(null));

console.log(newObject);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Niladri Basu
Niladri Basu

Reputation: 10604

You can also use Array#reduce to do something like this perhaps:

var originalObj = [
	{
		title: "header",
		content: "Some header text here",
		contentHTML: "<p>Some header text here</p>"
	},
	{
		title: "footer",
		content: "Some footer text here",
		contentHTML: "<p>Some footer text here</p>"
	},
	{
		title: "sidebar",
		content: "Some sidbar text here",
		contentHTML: "<p>Some sidebar text here</p>"
	}
];

var output = originalObj.reduce((accumulator, ele) => {
  accumulator[ele['title']] = {'text': ele['content'], 'content': ele['contentHTML']}
  return accumulator;
}, {})

console.log(output);

Upvotes: 1

Andrew Bone
Andrew Bone

Reputation: 7291

You were overriding newObject with the contents of tempObj it's much easier if you just write directly into newObject like this.

var originalObj = [{
    title: "header",
    content: "Some header text here",
    contentHTML: "<p>Some header text here</p>"
  },
  {
    title: "footer",
    content: "Some footer text here",
    contentHTML: "<p>Some footer text here</p>"
  },
  {
    title: "sidebar",
    content: "Some sidbar text here",
    contentHTML: "<p>Some sidebar text here</p>"
  }
];
let newObject = {};
for (let item of originalObj) {
  newObject[item.title] = {
    text: item.content,
    content: item.contentHTML
  }
}
console.log(newObject);

I hope this makes sense

Upvotes: 1

Related Questions