javascript arrays sum reduce

Suma de partes de una matriz-JavaScript



arrays reduce (6)

Tratando de resolver este desafío en codewars . Según el desafío, las partes de la matriz:

ls = [0, 1, 3, 6, 10]

Son

ls = [0, 1, 3, 6, 10] ls = [1, 3, 6, 10] ls = [3, 6, 10] ls = [6, 10] ls = [10] ls = []

Y tenemos que devolver una matriz con las sumas de esas partes.

Así que mi código es el siguiente:

function partsSums(ls) { let arrayOfSums = []; while(ls.length > 0) { let sum = ls.reduce((a, b) => a + b); arrayOfSums.push(sum); ls.shift(); } return arrayOfSums; } console.log(partsSums([0, 1, 3, 6, 10]));

El problema es que quiere que agreguemos la última suma 0 cuando la matriz está vacía. Así que deberíamos estar recibiendo:

[20, 20, 19, 16, 10, 0]

En lugar de

[20, 20, 19, 16, 10]

Así que intenté esto:

function partsSums(ls) { let arrayOfSums = []; while(ls.length > 0) { let sum = ls.reduce((a, b) => a + b); arrayOfSums.push(sum); ls.shift(); } arrayOfSums.push(0); return arrayOfSums; } console.log(partsSums([0, 1, 3, 6, 10]));

Y esto:

function partsSums(ls) { ls.push(0); let arrayOfSums = []; while(ls.length > 0) { let sum = ls.reduce((a, b) => a + b); arrayOfSums.push(sum); ls.shift(); } return arrayOfSums; }

Pero esto causó errores de tiempo de espera de ejecución en Codewars:

Tiempo de espera agotado (12000 ms)

Así que también intenté:

function partsSums(ls) { let arrayOfSums = []; while(ls.length > -1) { let sum = ls.reduce((a, b) => a + b); arrayOfSums.push(sum); ls.shift(); } return arrayOfSums; }

Pero ahora esto causa un TypeError:

TypeError: Reducción de la matriz vacía sin valor inicial

No entiendo el concepto de cómo obtener 0 en la matriz cuando todos los valores se han desplazado. El desafío parece querer 0 como la "suma" final de la matriz, incluso cuando la matriz está vacía. Pero no puedes reducir una matriz vacía. ¿Qué más puedo hacer aquí?

EDITAR : Intenté agregar valor inicial al método de reducción:

function partsSums(ls) { let arrayOfSums = []; while(ls.length > 0) { let sum = ls.reduce((a, b) => a + b, 0); arrayOfSums.push(sum); ls.shift(); } return arrayOfSums; }

Lamentablemente esto todavía falla la prueba básica:

espera [] que sea profundamente igual [0]


Aquí hay una cosa que podrías hacer

function partsSums(ls) { if(!ls.length) return [0]; let prevTotal = ls.reduce((a,b) => a + b); return [prevTotal, ...ls.map(val => prevTotal -= val)] } console.log(partsSums([0, 1, 3, 6, 10]));


No hay razón para calcular la suma una y otra vez. En una matriz larga, esto será muy ineficiente (O (n²)) y podría explicar sus errores de tiempo de espera. Calcule la suma al principio y luego reste cada elemento de ella en un bucle.

ls = [0, 1, 3, 6, 10] function partsSums(ls) { let sum = ls.reduce((sum, n) => sum + n, 0) res = [sum] for (let i = 1; i <= ls.length; i++){ sum -= ls[i-1] res.push(sum ) } return res } console.log(partsSums(ls))


Otra solución que pasó todas las pruebas:

function partsSums(ls) { let result = [0], l = ls.length - 1; for (let i = l; i >= 0; i--) { result.push(ls[i] + result[ l - i]); } return result.reverse(); } console.log(partsSums([])); console.log(partsSums([0, 1, 3, 6, 10])); console.log(partsSums([1, 2, 3, 4, 5, 6])); console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));


Podría repetir desde el final y tomar este valor más el último valor insertado del conjunto de resultados.

Este enfoque funciona con un solo bucle y sin calcular la suma máxima de antemano.

function partsSums(ls) { var result = [0], i = ls.length; while (i--) { result.unshift(ls[i] + result[0]); } return result; } console.log(partsSums([0, 1, 3, 6, 10])); console.log(partsSums([]));

.as-console-wrapper { max-height: 100% !important; top: 0; }

Con push y reverse .

function partsSums(ls) { var result = [0], l = 0, i = ls.length; while (i--) result.push(l += ls[i]); return result.reverse(); } console.log(partsSums([0, 1, 3, 6, 10])); console.log(partsSums([]));

.as-console-wrapper { max-height: 100% !important; top: 0; }


Puede usar for bucle con sector y cuando i == 0 puede dividir len + 1 que le devolverá la matriz vacía y la suma será 0.

function partsSums(arr) { const res = [], len = arr.length for (let i = len; i > -1; i--) { res.push(arr.slice(-i || len + 1).reduce((a, n) => a + n, 0)) } return res; } console.log(partsSums([0, 1, 3, 6, 10])); console.log(partsSums([1, 2, 3, 4, 5, 6])); console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));

También puede usar dos de reduce doble y, si no hay un elemento siguiente, presione cero.

function partsSums(arr) { const sum = arr => arr.reduce((r, e) => r + e, 0); return arr.reduce((r, e, i, a) => { const res = sum(a.slice(i, a.length)); return r.concat(!a[i + 1] ? [res, 0] : res) }, []) } console.log(partsSums([0, 1, 3, 6, 10])); console.log(partsSums([1, 2, 3, 4, 5, 6])); console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));


prueba esto con recursion

function partsSums(ls) { let sum = ls.reduce((a, b) => a + b, 0); return ls.length > 0 ? [sum].concat(partsSums(ls.slice(1))) : [0]; } console.log(partsSums([0, 1, 3, 6, 10])); console.log(partsSums([1, 2, 3, 4, 5, 6])); console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));