Estoy tratando de recrear el método _.reduce de la biblioteca de guiones bajos desde cero, pero estoy fallando en tres casos de prueba. 1. Debería continuar llamando al iterador incluso si el iterador devuelve indefinido. 2. Debería pasar cada elemento de la matriz al iterador si se pasa una nota. 3. Debería pasar primero el segundo elemento de la matriz al iterador si no se pasa una nota. He estado mirando los documentos y Pensé que iterator(accumulator, collection[1], 1, collection) cubriría el tercer caso, pero supongo que no.
_.reduce = function(collection, iterator, accumulator) { // TIP: To support both arrays and objects, try re-using each() here if (accumulator === undefined) { accumulator = collection[0]; iterator(accumulator, collection[1]); } _.each(collection, function(val) { iterator(accumulator, val); } ); return accumulator; };
Algunos asuntos:
En caso de que el accumulator
no esté definido, su código primero llama al iterator
con collection[1]
, pero si collection
no es una matriz, esto no representará el segundo elemento de la colección. Por ejemplo, el segundo elemento en {a:1, b:2}
sería collection.b
.
En caso de que el accumulator
no esté definido, su código continuará ejecutando _.each
. cada uno, lo que llamará al iterator
en el primer elemento de la colección, que desea evitar...
Su código ignora el valor devuelto por la llamada de iterator
. Debería capturar este valor de retorno y asignarlo al accumulator
El iterator
debe llamarse con un tercer argumento: el índice/clave del valor.
El iterator
debe llamarse con un cuarto argumento: la colección completa que se está iterando
Corrección:
_.reduce = function(collection, iterator, accumulator) { _.each(collection, function(val, i) { if (accumulator === undefined && i === 0) accumulator = val; else accumulator = iterator(accumulator, val, i, collection); }); return accumulator; }; // Tests console.log(_.reduce([1,2,3], (a, b) => a+b, 1) === 7); console.log(_.reduce([1,2,3], (a, b) => a+b) === 6); console.log(_.reduce({a: 1, b: 2, c:3}, (a, b, i) => a+b, 0) === 6); console.log(_.reduce({a: 1, b: 2, c:3}, (a, b, i) => a+i, "") === "abc"); console.log(_.reduce([], (a, b) => a+b, 0) === 0); console.log(_.reduce([], (a, b) => a+b) === undefined); console.log(_.reduce([1,2,3], (a, b, i, all) => a + b * all[i-1] ) === 9);
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd.min.js"></script>