'Loop or map array inside the JavaScript object
I have an array of javascript objects like:
const arrayData = [
{ name: "campaign 1", date: "2022-05-13", milestones:[{name:"Planning", targetDate: "2022-05-25"},
{name:"Funding", targetDate: "2022-05-30"},
{name:"Delievery", targetDate: "2022-05-31"}]
},
{ name: "campaign 2", date: "2022-06-19", milestones:[{name:"Planning", targetDate: "2022-08-12"},
{name:"Funding", targetDate: "2022-09-01"},
{name:"Delievery", targetDate: "2022-06-08"}]
},
{ name: "campaign 3", date: "2022-07-11", milestones:[{name:"Planning", targetDate: "2022-06-13"},
{name:"Funding", targetDate: "2022-07-10"},
{name:"Delievery", targetDate: "2022-08-01"}]
},
];
I want to convert it into this form:
const arrayData = [
{ name: "campaign 1", date: "2022-05-13", Planning:"2022-05-25", Funding: "2022-05-30", Delievery: "2022-05-31"},
{ name: "campaign 2", date: "2022-06-19", Planning: "2022-08-12", Funding: "2022-09-01", Delievery: "2022-06-08"},
{ name: "campaign 3", date: "2022-07-11", Planning: "2022-06-13", Funding: "2022-07-10", Delievery: "2022-08-01"}
];
I tried to do it this way:
let newData = [];
for (let i in arrayData) {
newData.push({
campaignName: arrayData[i].campaignName,
date: arrayData[i].date,
arrayData[i].milestones.map(item, index)=>(
[arrayData[i].milestones[j].name]:
arrayData[i].milestones[j].targetedDate,
)
});
}
But, it didn't work for me. Kindly provide the solutions of it. Thanks
Solution 1:[1]
This will iterate the milestone
property only once for each object. That would be faster.
const arrayData=[{name:"campaign 1",date:"2022-05-13",milestones:[{name:"Planning",targetDate:"2022-05-25"},{name:"Funding",targetDate:"2022-05-30"},{name:"Delievery",targetDate:"2022-05-31"}]},{name:"campaign 2",date:"2022-06-19",milestones:[{name:"Planning",targetDate:"2022-08-12"},{name:"Funding",targetDate:"2022-09-01"},{name:"Delievery",targetDate:"2022-06-08"}]},{name:"campaign 3",date:"2022-07-11",milestones:[{name:"Planning",targetDate:"2022-06-13"},{name:"Funding",targetDate:"2022-07-10"},{name:"Delievery",targetDate:"2022-08-01"}]}];
const formattedData = arrayData.map( obj => {
const tempObj = {
name: obj.name,
date: obj.date
}
obj.milestones.forEach(milestone => {
tempObj[milestone.name] = milestone.targetDate;
});
return tempObj;
});
console.log(formattedData);
Solution 2:[2]
Use Array#map
and object destructuring as in the following demo. This demo assumes that the milestones elements are always in the order Planning, Funding, Delivery
. If the order is bound to be different, I'll provide a second demo that would work for whatever order they appear in.
const arrayData = [ { name: "campaign 1", date: "2022-05-13", milestones:[{name:"Planning", targetDate: "2022-05-25"}, {name:"Funding", targetDate: "2022-05-30"}, {name:"Delievery", targetDate: "2022-05-31"}] }, { name: "campaign 2", date: "2022-06-19", milestones:[{name:"Planning", targetDate: "2022-08-12"}, {name:"Funding", targetDate: "2022-09-01"}, {name:"Delievery", targetDate: "2022-06-08"}] }, { name: "campaign 3", date: "2022-07-11", milestones:[{name:"Planning", targetDate: "2022-06-13"}, {name:"Funding", targetDate: "2022-07-10"}, {name:"Delievery", targetDate: "2022-08-01"}] }],
output = arrayData.map(
({milestones:[
{ targetDate:Planning },
{ targetDate:Funding },
{ targetDate:Delivery }
],
...rest}) =>
({...rest,Planning,Funding,Delivery})
);
console.log( output );
Alternatively ....
You can use Array#map
and Array#reduce
as in the following demo. This should work for any order AND NUMBER of milestones.
const arrayData = [ { name: "campaign 1", date: "2022-05-13", milestones:[{name:"Planning", targetDate: "2022-05-25"}, {name:"Funding", targetDate: "2022-05-30"}, {name:"Delievery", targetDate: "2022-05-31"}] }, { name: "campaign 2", date: "2022-06-19", milestones:[{name:"Planning", targetDate: "2022-08-12"}, {name:"Funding", targetDate: "2022-09-01"}, {name:"Delievery", targetDate: "2022-06-08"}] }, { name: "campaign 3", date: "2022-07-11", milestones:[{name:"Planning", targetDate: "2022-06-13"}, {name:"Funding", targetDate: "2022-07-10"}, {name:"Delievery", targetDate: "2022-08-01"}] }],
output = arrayData.map(
({milestones,...rest}) =>
({
...rest,
...milestones.reduce(
(acc,{name,targetDate}) =>
({...acc, [name]: targetDate}), {}
)
})
);
console.log( output );
As for your code ....
- You introduced a property
campaignName
that does not exist in your data - Rather than use
Array#map
you can useArray#reduce
in combination with the spread...
operator as in the following demo:
const arrayData = [ { name: "campaign 1", date: "2022-05-13", milestones:[{name:"Planning", targetDate: "2022-05-25"}, {name:"Funding", targetDate: "2022-05-30"}, {name:"Delievery", targetDate: "2022-05-31"}] }, { name: "campaign 2", date: "2022-06-19", milestones:[{name:"Planning", targetDate: "2022-08-12"}, {name:"Funding", targetDate: "2022-09-01"}, {name:"Delievery", targetDate: "2022-06-08"}] }, { name: "campaign 3", date: "2022-07-11", milestones:[{name:"Planning", targetDate: "2022-06-13"}, {name:"Funding", targetDate: "2022-07-10"}, {name:"Delievery", targetDate: "2022-08-01"}] }],
newData = [];
for (let i in arrayData) {
newData.push({
name: arrayData[i].name,
date: arrayData[i].date,
...arrayData[i].milestones.reduce(
(acc, {name,targetDate}) =>
({...acc, [name]:targetDate}),{}
)
});
}
console.log( newData );
Solution 3:[3]
Something like this?
arrayData.map(item => ({
name: item.name,
date: item.date,
Planning: item.milestones.find(milestone => milestone.name === 'Planning')?.targetDate,
Funding: item.milestones.find(milestone => milestone.name === 'Funding')?.targetDate,
Delievery: item.milestones.find(milestone => milestone.name === 'Delievery')?.targetDate,
}))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Gerjan |