- How can I add data by grouping with country label and create data array that has 12 index indicating months and containing value of data before grouping. I need help, how to push and group the data according to the month number. e.x
arr = [
{ label: 'US', data: '10', monthNumber: 1 },
{ label: 'US', data: '2', monthNumber: 3 },
{ label: 'US', data: '60', monthNumber: 2 },
{ label: 'UK', data: '10', monthNumber: 5 },
{ label: 'SA', data: '1', monthNumber: 1 },
{ label: 'CA', data: '70', monthNumber: 1 },
{ label: 'SA', data: '10', monthNumber: 12 },
];
now i need the results to be like
[
{ label: 'US', data: [10,60,2,0,0,0,0,0,0,0,0,0] },
{ label: 'UK', data: [0,0,0,0,10,0,0,0,0,0,0,0] },
{ label: 'SA', data: [1,0,0,0,0,0,0,0,0,0,0,10] },
{ label: 'CA', data: [70,0,0,0,0,0,0,0,0,0,0,0] },
];
CodePudding user response:
Create a new object by reducing
over the array using the labels as object keys, and initialising the property value as an object with a label, and a pre-filled array of zeros. Then update the array with the data at the relevant position.
const arr=[{label:"US",data:"10",monthNumber:1},{label:"US",data:"2",monthNumber:3},{label:"US",data:"60",monthNumber:2},{label:"UK",data:"10",monthNumber:5},{label:"SA",data:"1",monthNumber:1},{label:"CA",data:"70",monthNumber:1},{label:"SA",data:"10",monthNumber:12}];
function grouper(arr) {
// `reduce` over the array passing in an
// empty object as the initial accumulator value
const out = arr.reduce((acc, c) => {
// Destructure the properties from the current
// iterated object
const { label, data, monthNumber } = c;
// If the label doesn't exist as a key on the object
// create it, and assign an object as its value, using
// the label, and adding a pre-filled array of zeros to
// its data property
acc[label] ??= { label, data: new Array(12).fill(0) };
// Update the data array with the data value at the
// appropriate position
acc[label].data[monthNumber - 1] = Number(data);
// Return the accumulator for the next iteration
return acc;
}, {});
// Finally get the array of updated objects
// from the accumulated data
return Object.values(out);
}
console.log(grouper(arr));
Additional documentation
CodePudding user response:
For grouping, you could make use of reduce
const arr = [
{ label: "US", data: "10", monthNumber: 1 },
{ label: "US", data: "2", monthNumber: 3 },
{ label: "US", data: "60", monthNumber: 2 },
{ label: "UK", data: "10", monthNumber: 5 },
{ label: "SA", data: "1", monthNumber: 1 },
{ label: "CA", data: "70", monthNumber: 1 },
{ label: "SA", data: "10", monthNumber: 12 },
]
let res = arr.reduce((acc, { label, monthNumber, data }) => {
if (!acc[label]) acc[label] = Array(12).fill(0)
acc[label][monthNumber - 1] = Number(data)
return acc
}, {})
res = Object.entries(res).map(([label, data]) => ({ label, data }))
console.log(res)
CodePudding user response:
- First I have extracted the label from the current array.
- After that, I have a loop through those labels, and inside that loop through the array, and created an object with store values of data and label.
- please see the comments for a better understanding.
Important thing to notice here is that for the same month number for labels value will be replaced with the last one.
arr = [{
label: 'US',
data: '10',
monthNumber: 1
},
{
label: 'US',
data: '2',
monthNumber: 3
},
{
label: 'US',
data: '60',
monthNumber: 2
},
{
label: 'UK',
data: '10',
monthNumber: 5
},
{
label: 'SA',
data: '1',
monthNumber: 1
},
{
label: 'CA',
data: '70',
monthNumber: 1
},
{
label: 'SA',
data: '10',
monthNumber: 12
},
];
const labels = [];
const result = [];
// extracting unique labels
arr.forEach(item => {
!labels.includes(item.label) && labels.push(item.label);
})
// looping through labels
labels.forEach(label => {
// creating empty object
const object = {};
// creating data array with 12 values by default 0
const data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// loop though array values
arr.forEach(item => {
// checking if current outer label is matching with array label
if (item.label == label) {
// if abive condition true add label key in object with value of current outer label
object["label"] = label;
// updating month value
data[item.monthNumber - 1] = item.data;
}
// adding data in object with key data.
object["data"] = data;
})
// pushing final object in result
result.push(object);
})
//printing final result
console.log(result);
CodePudding user response:
Good starting point will be to group the data by label first.
Then take the values from that to remap the data.
Create a Month array generating a new array with 0 values
Loop through and add the data to the month array based on MonthNumber
const remap = () => {
let arr = [
{ label: 'US', data: '10', monthNumber: 1 },
{ label: 'US', data: '2', monthNumber: 3 },
{ label: 'US', data: '60', monthNumber: 2 },
{ label: 'UK', data: '10', monthNumber: 5 },
{ label: 'SA', data: '1', monthNumber: 1 },
{ label: 'CA', data: '70', monthNumber: 1 },
{ label: 'SA', data: '10', monthNumber: 12 }
];
return Object.values(
arr.reduce((acc, v) => {
if (!acc.hasOwnProperty(v.label)) {
acc[v.label] = [];
}
acc[v.label].push(v);
return acc;
}, {})
).map((flatData) => {
const label = Array.isArray(flatData) && flatData.length > 0 ? flatData[0].label : '';
const monthArray = new Array(12).fill(0);
flatData.forEach(({ data, monthNumber }) => {
monthArray[monthNumber] = parseInt(data);
});
return { label, data: monthArray };
});
};
console.log(remap())
CodePudding user response:
Try this solution:
function setupGraph(arr){
data = [];
for (let i = 0; i < arr.length; i ) {
let found = false;
for (let j = 0; j < data.length; j ) {
if (data[j].label === arr[i].label) {
data[j].data[arr[i].monthNumber - 1] = Number(arr[i].data);
found = true;
break;
}
}
if (!found) {
data.push({ label: arr[i].label, data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] });
data[data.length - 1].data[arr[i].monthNumber - 1] = Number(arr[i].data);
}
}
return data;
}
Testing the function:
arr = [
{ label: 'US', data: '10', monthNumber: 1 },
{ label: 'US', data: '2', monthNumber: 3 },
{ label: 'US', data: '60', monthNumber: 2 },
{ label: 'UK', data: '10', monthNumber: 5 },
{ label: 'SA', data: '1', monthNumber: 1 },
{ label: 'CA', data: '70', monthNumber: 1 },
{ label: 'SA', data: '10', monthNumber: 12 },
];
let result = setupGraph(arr)
console.log(result);
[
{
label: 'US',
data: [
10, 60, 2, 0, 0,
0, 0, 0, 0, 0,
0, 0
]
},
{
label: 'UK',
data: [
0, 0, 0, 0, 10,
0, 0, 0, 0, 0,
0, 0
]
},
{
label: 'SA',
data: [
1, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 10
]
},
{
label: 'CA',
data: [
70, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0
]
}
]