I have the following code that generates a table from some data that comes from an array, the code shows me the values of each product per week and its total in the following way:
-----------------------------------------------------
Land | Product | 25 | 26 | Total |
-----------------------------------------------------
FINCA1 | ROSA | 2000 | 1254 | 3254 |
-----------------------------------------------------
FINCA2 | ROSA | 1900 | 123 | 2023 |
-----------------------------------------------------
FINCA3 | ROSA | 350 | 200 | 550 |
-----------------------------------------------------
FINCA3 | ROSA1 | 410 | 0 | 410 |
-----------------------------------------------------
TOTAL | | 4660 | 1577 | 6237 |
------------------------------------------------------
var data = [
{id:1, land: 'FINCA1', product: "ROSA", week:25, quantity: 2000},
{id:1, land: 'FINCA2', product: "ROSA", week:25, quantity: 1900},
{id:1, land: 'FINCA3', product: "ROSA", week:25, quantity: 350},
{id:1, land: 'FINCA3', product: "ROSA1",week:25, quantity: 410},
{id:1, land: 'FINCA1', product: "ROSA", week:26, quantity: 1254},
{id:1, land: 'FINCA2' , product: "ROSA",week:26, quantity: 123},
{id:1, land: 'FINCA3' , product: "ROSA",week:26, quantity: 200}
];
//Obtengo los keys del objeto para crear el Thead de la tabla y los guardo en una variable
var tabla = document.createElement('table');
var tableHead = document.createElement('tr');
Object.keys(data[0]).forEach(prop=>{
if(prop != 'week' && prop != 'quantity')
tableHead.innerHTML += '<th>'+prop+'</th>';
});
var semanas = data.reduce( (semanas_, elemento)=>{
if(semanas_.indexOf(elemento.week) == -1)
semanas_.push(elemento.week)
return semanas_;
}, []);
semanas.forEach( semana=>{
tableHead.innerHTML += '<th>'+semana+'</th>';
});
var total_semanas = [];
tableHead.innerHTML += '<th>Total</th>';
tabla.appendChild(tableHead);
var tbody = document.createElement('tbody');
tabla.appendChild(tbody);
document.querySelector('body').appendChild(tabla);
var arrayOrganizado = data.reduce((arr, item)=>{
var t = total_semanas.find(e=> e.semana === item.week);
if (t) t.total += item.quantity;
else total_semanas.push({ semana : item.week, total : item.quantity });
item.week = {
numero : item.week,
cantidad : item.quantity
}
var ele = arr.find(it=>it.land === item.land && it.product === item.product);
if(ele){
ele.week.push(item.week);
ele.total = ele.week.reduce((a, b)=> a + b.cantidad, 0);
} else {
item.week = [item.week];
item.total = item.quantity;
arr.push(item);
}
return arr;
}, []);
arrayOrganizado.forEach(fila=>{
var f = Object.keys(fila).reduce( (a, b)=>{
//console.log(b);
if(b != 'week' && b != 'quantity' && b != 'total')
return a + '<td>' + fila[b] + '</td>';
return a;
}, '');
tbody.innerHTML += f + semanas.reduce( (a, _, i)=>a + '<td>' + (fila.week[i] ? fila.week[i].cantidad : 0) + '</td>', '') + '<td>' + fila.total + '</td>';
});
var f = Object.keys(arrayOrganizado[0]).reduce( (a, b)=>{
//console.log(b);
if(b != 'week' && b != 'quantity' && b != 'total')
return a + '<td> ---- </td>';
return a;
}, '');
tbody.innerHTML += f + total_semanas.reduce( (a, _, i)=>a + '<td>' + _.total + '</td>', '') + '<td>' + total_semanas.reduce( (a, b) => a.total + b.total) + '</td>';
So far everything is fine, the problem is that when you increase the weeks, there may be weeks that do not have values and the result is 0, but instead of putting that value in the corresponding week, you put it in the last one, I explain:
The arrangement can arrive as follows
var data = [
{id:1, land: 'FINCA1', product: "ROSA", week:25, quantity: 2000},
{id:1, land: 'FINCA2', product: "ROSA", week:25, quantity: 1900},
{id:1, land: 'FINCA3', product: "ROSA", week:25, quantity: 350},
{id:1, land: 'FINCA3', product: "ROSA1",week:25, quantity: 410},
{id:1, land: 'FINCA1', product: "ROSA", week:26, quantity: 1254},
{id:1, land: 'FINCA2' , product: "ROSA", week:26, quantity: 123},
{id:1, land: 'FINCA3' , product: "ROSA", week:26, quantity: 200},
{id:1, land: 'FINCA3' , product: "ROSA", week:24, quantity: 200}
{id:1, land: 'FINCA3' , product: "ROSA", week:23, quantity: 1200}
];
The table should look like this:
-----------------------------------------------------------------------
Land | Product | 23 | 24 | 25 | 26 | Total |
-----------------------------------------------------------------------
FINCA1 | ROSA | 0 | 0 | 2000 | 1254 | 3254 |
-----------------------------------------------------------------------
FINCA2 | ROSA | 0 | 0 | 1900 | 123 | 2023 |
-----------------------------------------------------------------------
FINCA3 | ROSA | 1200 | 200 | 350 | 200 | 1950 |
-----------------------------------------------------------------------
FINCA3 | ROSA1 | 0 | 0 | 410 | 0 | 410 |
-----------------------------------------------------------------------
TOTAL | | 1200 | 200 | 4660 | 1577 | 7637 |
-----------------------------------------------------------------------
However, the table looks like this;
-----------------------------------------------------------------------
Land | Product | 23 | 24 | 25 | 26 | Total |
-----------------------------------------------------------------------
FINCA1 | ROSA | 2000 | 1254 | 0 | 0 | 3254 |
-----------------------------------------------------------------------
FINCA2 | ROSA | 1900 | 123 | 0 | 0 | 2023 |
-----------------------------------------------------------------------
FINCA3 | ROSA | 1200 | 200 | 350 | 200 | 1950 |
-----------------------------------------------------------------------
FINCA3 | ROSA1 | 410 | 0 | 0 | 0 | 410 |
-----------------------------------------------------------------------
TOTAL | | 1200 | 200 | 4660 | 1577 | 7637 |
-----------------------------------------------------------------------
I think it's the function that reduces the problem in this part:
tbody.innerHTML += f + semanas.reduce( (a, _, i)=>a + '<td>' + (fila.week[i] ? fila.week[i].cantidad : 0) + '</td>', '') + '<td>' + fila.total + '</td>';
I do not know if there is another similiar function that does the same, or I do not know if it is that function, I appreciate your help