Dada la siguiente matriz, necesito reducirla por los nombres de las funciones de los empleados y también sumar algunas filas.
Reduzca si Fila[1] es igual a cualquier otra, y sume Fila[2] y Fila[5].
matriz de ejemplo
[ [ 20, 'AJUDANTE GERAL ', 2, 'HH', 6.36, 12.72, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 20, 'AJUDANTE GERAL ', 0.15, 'HH', 6.36, 0.954, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ], [ 0, 'ISOLADOR', 2, 'HH', 10.68, 21.36, '', '' ], [ 0, 'ISOLADOR', 8, 'HH', 10.68, 85.44, '', '' ], [ 0, 'ISOLADOR', 0.15, 'HH', 10.68, 1.6019999999999999, '', '' ], [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ] ]resultado esperado
[ [ 20, 'AJUDANTE GERAL ', 18.15, 'HH', 6.36, 115.434, '', '' ], [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ], [ 0, 'ISOLADOR', 10.15, 'HH', 10.68, 108.402, '', '' ], [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ] ] Pude lograr esto usando algunos for loops que creo que no son reales, ya que estoy cambiando valores durante el bucle. Está funcionando, sin embargo, me gustaría entender cómo podría hacerlo con reduce y maps.
// sheetMapped is the array with all data duplicated // uniqueRows is where I am keeping only the unique values with the sum values let uniqueRows = []; for (let i = 0; i < sheetMapped.length; i += 1) { let row = sheetMapped[i]; let found = false; for (let j = 0; j < uniqueRows.length; j += 1) { let rowUniqueTest = uniqueRows[j]; if (row[1] === rowUniqueTest[1]) { found = true; uniqueRows[j][2] += row[2]; uniqueRows[j][5] += row[5]; break; } } if (!found) { uniqueRows.push(row); } } Ya probé algunos ejemplos usando Array.from , set Maps , reduces , pero fueron un poco difíciles de entender ya que estoy trabajando con más datos en una matriz y no solo con key/value pairs .
Gracias por adelantado
Esto se puede hacer con una operación 'agrupar por' bastante estándar usando reduce() .
El fragmento a continuación usa un Map , ya que mantiene el orden de inserción mientras que un objeto ordena las propiedades numéricas. El Map resultante se vuelve a convertir en una matriz usando Array.from() invocado en Map.values()
const input = [ [ 20, 'AJUDANTE GERAL ', 2, 'HH', 6.36, 12.72, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 20, 'AJUDANTE GERAL ', 0.15, 'HH', 6.36, 0.954, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ], [ 0, 'ISOLADOR', 2, 'HH', 10.68, 21.36, '', '' ], [ 0, 'ISOLADOR', 8, 'HH', 10.68, 85.44, '', '' ], [ 0, 'ISOLADOR', 0.15, 'HH', 10.68, 1.6019999999999999, '', '' ], [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ], ]; const result = Array.from( input .reduce((a, row) => { if (!a.has(row[1])) { a.set(row[1], [...row]); } else { const _row = a.get(row[1]); _row[2] += row[2]; _row[5] += row[5]; } return a; }, new Map()) .values() ); console.log(result); .as-console-wrapper { max-height: 100% !important; top: 0; }con una matriz como acumulador en reduce , esto es pan comido, eche un vistazo al código a continuación
var data = [ [ 20, 'AJUDANTE GERAL ', 2, 'HH', 6.36, 12.72, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 20, 'AJUDANTE GERAL ', 0.15, 'HH', 6.36, 0.954, '', '' ], [ 20, 'AJUDANTE GERAL ', 8, 'HH', 6.36, 50.88, '', '' ], [ 125, 'CALDEREIRO', 8, 'HH', 13.05, 104.4, '', '' ], [ 0, 'ISOLADOR', 2, 'HH', 10.68, 21.36, '', '' ], [ 0, 'ISOLADOR', 8, 'HH', 10.68, 85.44, '', '' ], [ 0, 'ISOLADOR', 0.15, 'HH', 10.68, 1.6019999999999999, '', '' ], [ 585, 'PINTOR', 2, 'HH', 10.91, 21.82, '', '' ] ] data = data.reduce((a,e)=>{ let sInd = a.findIndex(each=>each.indexOf(e[1]) != -1) if(sInd >= 0){ // if entry added already a[sInd][2] += e[2] a[sInd][5] += e[5] } else{a.push(e)} // if new entry return a },[]) console.log(data.join("\n"))Si la fila y la columna son fijas, puede usar el siguiente código de muestra. Combinar como un objeto y obtener todos los valores.
const data = [ [20, "AJUDANTE GERAL ", 2, "HH", 6.36, 12.72, "", ""],[20, "AJUDANTE GERAL ", 8, "HH", 6.36, 50.88, "", ""],[20, "AJUDANTE GERAL ", 0.15, "HH", 6.36, 0.954, "", ""],[20, "AJUDANTE GERAL ", 8, "HH", 6.36, 50.88, "", ""], [125, "CALDEREIRO", 8, "HH", 13.05, 104.4, "", ""], [0, "ISOLADOR", 2, "HH", 10.68, 21.36, "", ""],[0, "ISOLADOR", 8, "HH", 10.68, 85.44, "", ""],[0, "ISOLADOR", 0.15, "HH", 10.68, 1.6019999999999999, "", ""],[585, "PINTOR", 2, "HH", 10.91, 21.82, "", ""], ]; const map = data.reduce((m, row) => { const id = row[0]; if (id in m) { m[id][2] += row[2]; m[id][5] += row[5]; } else { m[id] = row; } return m; }, {}); console.log(Object.values(map));