Eu tenho esses dados de amostra.
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'}
];
Quero criar duas propriedades nesses dados chamadas countBatch e countGroup .
Primeiro, preciso classificar os dados para mostrá-los em ordem crescente e agrupar cada dado do GroupCode, então crio este método:
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);
});
Agora, adicionarei a propriedade nos dados chamados countGroup e, em seguida, mostrarei apenas o valor contado nos primeiros dados do array, cada um do GroupCode, o restante deve estar em valor nulo . Por exemplo;
{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}
Para o resultado acima eu crio outro método: eu itero sobre o índice de sortedGroup
então uso Object.keys()
a função e então farei uma condição que se o índice for igual a 0, ele agrega valor na propriedade ( countGroup ). Caso contrário, torne o valor null . Aqui está o método que criei:
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);
});
});
Fazendo o código acima, agora posso obter o resultado que desejo. Aqui está uma demonstração.
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);
Por último, adicionarei a propriedade chamada countBatch nos dados. Como o valor contará o lote, crio uma variável e um método que conta o lote: Aqui está o método que usei:
const batchCounts = {};
data.forEach((item) => {
if (!batchCounts[item.BatchNumber]) {
batchCounts[item.BatchNumber] = 0;
}
batchCounts[item.BatchNumber]++;
});
E então, adicione o resultado batchCounts
dentro da iteração de sortedGroup
. Eu adiciono uma variável chamada batchCount
com valor de batchCounts[group[0].BatchNumber]
. Isso mostra o valor de contagem de BatchNunber e apenas passa para a iteração do grupo fazendodata.countBatch = batchCount;
O problema é; o valor de countBatch é inserido sempre que o valor countGroup é inserido. Quero apenas inserir o valor de countBatch nos primeiros dados de cada número de lote.
ATUAL
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);
ESPERADO
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);