I have this sample data.
let data = [
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 1, GroupCode: 'B'},
{BatchNumber: 1, GroupCode: 'C'},
{BatchNumber: 1, GroupCode: 'B'},
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 2, GroupCode: 'C'},
{BatchNumber: 2, GroupCode: 'B'},
{BatchNumber: 2, GroupCode: 'A'},
{BatchNumber: 2, GroupCode: 'C'}
];
I want to create a two property in this data named countBatch and countGroup.
First, I need to sort data to show them in ascending order and group each data of GroupNumber, so I create this method:
data.sort((a, b) => {
if (a.BatchNumber === b.BatchNumber) {
return a.GroupCode.localeCompare(b.GroupCode);
}
return a.BatchNumber - b.BatchNumber;
});
const sortedGroup = {};
data.forEach((item) => {
const key = `${item.BatchNumber}-${item.GroupCode}`;
if (!sortedGroup[key]) {
sortedGroup[key] = [];
}
sortedGroup[key].push(item);
});
Now, I will add property in the data named countGroup, and then show only the counted value in the first data of array each from GroupCode, the rest should be in null value. For example;
{BatchNumber: 1, GroupCode: 'A', countGroup: 3},
{BatchNumber: 1, GroupCode: 'A', countGroup: null},
{BatchNumber: 1, GroupCode: 'A', countGroup: null},
{BatchNumber: 1, GroupCode: 'B', countGroup: 2},
{BatchNumber: 1, GroupCode: 'B', countGroup: null},
{BatchNumber: 1, GroupCode: 'C', countGroup: 1},
{BatchNumber: 2, GroupCode: 'A', countGroup: 1},
{BatchNumber: 2, GroupCode: 'B', countGroup: 1},
{BatchNumber: 2, GroupCode: 'C', countGroup: 2},
{BatchNumber: 2, GroupCode: 'C', countGroup: null}
For the above result I create another method: I iterate over the index of sortedGroup so I use Object.keys() function and then I will make a condition that if index is equal to 0, it add value on the property(countGroup). Else, make the value to null.
Here’s the method I created:
var result = [];
Object.keys(sortedGroup).forEach((key) => {
const group = sortedGroup[key];
group.forEach((data, index) => {
if (index === 0) {
data.countGroup = group.length;
} else {
data.countGroup = null;
}
result.push(data);
});
});
Doing the above code, I can now get the result I want.
Here’s a demo.
let data = [
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 1, GroupCode: 'B'},
{BatchNumber: 1, GroupCode: 'C'},
{BatchNumber: 1, GroupCode: 'B'},
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 2, GroupCode: 'C'},
{BatchNumber: 2, GroupCode: 'B'},
{BatchNumber: 2, GroupCode: 'A'},
{BatchNumber: 2, GroupCode: 'C'}
];
data.sort((a, b) => {
if (a.BatchNumber === b.BatchNumber) {
return a.GroupCode.localeCompare(b.GroupCode);
}
return a.BatchNumber - b.BatchNumber;
});
const sortedGroup = {};
data.forEach((item) => {
const key = `${item.BatchNumber}-${item.GroupCode}`;
if (!sortedGroup[key]) {
sortedGroup[key] = [];
}
sortedGroup[key].push(item);
});
var result = [];
Object.keys(sortedGroup).forEach((key) => {
const group = sortedGroup[key];
group.forEach((data, index) => {
if (index === 0) {
data.countGroup = group.length;
} else {
data.countGroup = null;
}
result.push(data);
});
});
console.log(result);
Lastly, I will add the property named countBatch in the data. Since the value will count the Batch, I create a variable and a method that count the batch: Here’s the method I used:
const batchCounts = {};
data.forEach((item) => {
if (!batchCounts[item.BatchNumber]) {
batchCounts[item.BatchNumber] = 0;
}
batchCounts[item.BatchNumber]++;
});
And then, add the result of batchCounts inside the iteration of sortedGroup. I add variable called batchCount with value of batchCounts[group[0].BatchNumber]. This shows the count value of BatchNunber and just pass it to iterattion of group by doing data.countBatch = batchCount;
The PROBLEM is; the value of countBatch is inserted everytime the countGroup value is inserted. I want only to insert the value of countBatch in the first data of each batch number.
CURRENT
let data = [
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 1, GroupCode: 'B'},
{BatchNumber: 1, GroupCode: 'C'},
{BatchNumber: 1, GroupCode: 'B'},
{BatchNumber: 1, GroupCode: 'A'},
{BatchNumber: 2, GroupCode: 'C'},
{BatchNumber: 2, GroupCode: 'B'},
{BatchNumber: 2, GroupCode: 'A'},
{BatchNumber: 2, GroupCode: 'C'}
];
data.sort((a, b) => {
if (a.BatchNumber === b.BatchNumber) {
return a.GroupCode.localeCompare(b.GroupCode);
}
return a.BatchNumber - b.BatchNumber;
});
const sortedGroup = {};
data.forEach((item) => {
const key = `${item.BatchNumber}-${item.GroupCode}`;
if (!sortedGroup[key]) {
sortedGroup[key] = [];
}
sortedGroup[key].push(item);
});
const batchCounts = {};
data.forEach((item) => {
if (!batchCounts[item.BatchNumber]) {
batchCounts[item.BatchNumber] = 0;
}
batchCounts[item.BatchNumber]++;
});
var result = [];
Object.keys(sortedGroup).forEach((key) => {
const group = sortedGroup[key];
const batchCount = batchCounts[group[0].BatchNumber];
group.forEach((data, index) => {
if (index === 0) {
data.countBatch = batchCount;
data.countGroup = group.length;
} else {
data.countBatch = null;
data.countGroup = null;
}
result.push(data);
});
});
console.log(result);
EXPECTED
let expected = [
{BatchNumber: 1, GroupCode: 'A', countBatch: 6,countGroup: 3},
{BatchNumber: 1, GroupCode: 'A', countBatch: null,countGroup: null},
{BatchNumber: 1, GroupCode: 'A', countBatch: null,countGroup: null},
{BatchNumber: 1, GroupCode: 'B', countBatch: null,countGroup: 2},
{BatchNumber: 1, GroupCode: 'B', countBatch: null,countGroup: null},
{BatchNumber: 1, GroupCode: 'C', countBatch: null,countGroup: 1},
{BatchNumber: 2, GroupCode: 'A', countBatch: 4,countGroup: 1},
{BatchNumber: 2, GroupCode: 'B', countBatch: null,countGroup: 1},
{BatchNumber: 2, GroupCode: 'C', countBatch: null,countGroup: 2},
{BatchNumber: 2, GroupCode: 'C', countBatch: null,countGroup: null}
];
console.log(expected);