I am trying to turn a array that exists of objects with a nested array inside it into a new array that consist of the values inside the nested array separately(Might sound very complicated but example show very clear)
What I have:
const values = [{
geometry: {
"coordinates": [11.4828, 59.1264],
"Type": "point"
},
properties: {
Region: "Oklahoma",
sales: {
donuts: {
2005: 5,
2006: 8,
2007: 10
},
apples: {
2005: 10,
2006: 8,
2007: 10
}
}
}
},
{
geometry: {
"coordinates": [9.4828, 76.1264],
"Type": "point"
},
properties: {
Region: "Texas",
sales: {
donuts: {
2005: 8,
2006: 0,
2007: 7
},
apples: {
2005: 7,
2006: 9,
2007: 4
}
}
}
}
]
const filterValue = "donuts"
What My goal is:
newValues =[{geometry: {"coordinates": [11.4828, 59.1264],"Type":"point"},properties:{Region: "Oklahoma",value:5,time:2005}},{geometry: {"coordinates": [11.4828, 59.1264],"Type":"point"},properties:{Region: "Oklahoma",value:8,time:2006}},{geometry: {"coordinates": [11.4828, 59.1264],"Type":"point"},properties:{Region: "Oklahoma",value:10,time:2007}} AND SO ON FOR ALL THE values that are in const donuts/filter for each value. Could also switch out value for donuts if that is easier
}
]
What I have tried so far:
const newObject = []
values.map((value)=>{
console.log(value.properties.sales.donuts)
for (var key in value.properties.sales.donuts) {
if (value.properties.sales.donuts.hasOwnProperty(key)) {
newObject.push({...value,value.properties:{[key]:value.properties.sales.donuts[key]})
}
}
})
console.log(newObject)
CodePudding user response:
Your current syntax is invalid - value.properties: {
is not a valid key in an object literal. Since you want the output properties
property to contain data corresponding to the region and year too, you should include those in the object being pushed. Since you also don't need the year to be a key in the new object, but a value (with a value
property), the object being pushed should reflect that.
You should only use .map
when you're returning a value inside the mapper function to create a new array. If you're iterating only to perform side-effects, you should use a more appropriate generic iteration method, like for..of
or forEach
. In this case, since you want to create multiple objects in the output array from one associated object in the input array, .flatMap
would be more appropriate.
Map the .donuts
entries and return the new object with geometry
and properties
properties.
const values=[{geometry:{coordinates:[11.4828,59.1264],Type:"point"},properties:{Region:"Oklahoma",sales:{donuts:{2005:5,2006:8,2007:10},apples:{2005:10,2006:8,2007:10}}}},{geometry:{coordinates:[9.4828,76.1264],Type:"point"},properties:{Region:"Texas",sales:{donuts:{2005:8,2006:0,2007:7},apples:{2005:7,2006:9,2007:4}}}}];
const filterValue = "donuts";
const output = values.flatMap(({ geometry, properties }) =>
Object.entries(properties.sales[filterValue]).map(([year, saleCount]) => ({
geometry,
properties: {
Region: properties.Region,
value: saleCount,
time: year,
}
}))
);
console.log(output);
CodePudding user response:
You'll need a flatmap here
const values = [
{
geometry: {
coordinates: [11.4828, 59.1264],
Type: 'point',
},
properties: {
Region: 'Oklahoma',
sales: {
donuts: {
2005: 5,
2006: 8,
2007: 10,
},
apples: {
2005: 10,
2006: 8,
2007: 10,
},
},
},
},
{
geometry: {
coordinates: [9.4828, 76.1264],
Type: 'point',
},
properties: {
Region: 'Texas',
sales: {
donuts: {
2005: 8,
2006: 0,
2007: 7,
},
apples: {
2005: 7,
2006: 9,
2007: 4,
},
},
},
},
];
const mapData = (data, filterBy) => {
return data.flatMap((state) => {
return Object.entries(state.properties.sales[filterBy]).map(
([time, value]) => {
return {
...state,
properties: {
region: state.properties.Region,
time,
value,
},
};
}
);
});
};
const mappedDonuts = mapData(values, 'donuts');
console.log(mappedDonuts);