Usar la función reduce para devolver una matriz

5 minutos de lectura

¿Por qué cuando quiero usar la función de inserción dentro de la función de reducción para devolver una nueva matriz, aparece un error? Sin embargo, cuando uso el método concat dentro de la función de reducción, devuelve una nueva matriz sin problemas.

Todo lo que intento hacer es pasar una matriz a la función de reducción y devolver la misma matriz.

var store = [0,1,2,3,4];

var stored = store.reduce(function(pV,cV,cI){
  console.log("pv: ", pV);
  return pV.push(cV);
},[]);

Esto devuelve un error. Pero cuando uso concat:

var store = [0,1,2,3,4];

var stored = store.reduce(function(pV,cV,cI){
  console.log("pv: ", pV);
  return pV.concat(cV);
},[]);

Devuelve la misma matriz.

¿Alguna idea de por qué?

  • return PV.push significa que en la próxima iteración, PV será un número, no una matriz, porque empujar devuelve la longitud de la matriz; si lo desea, puede hacerlo return pV.push(cV), pV; – sin embargo, no hay ningún beneficio excepto por 1 línea de código menos, es decir pV.push(cV); return pV;

    – Jaromanda X

    16 de febrero de 2016 a las 11:27


  • si todo lo que quiere hacer es “copiar” la matriz … var stored = store.slice(); servirá

    – Jaromanda X

    16/02/2016 a las 11:30


  • @Andy te importaría dar más detalles? los documentos literalmente estado map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results que parece describir perfectamente lo que estaba haciendo el interrogador.

    – Jamiec

    16 de febrero de 2016 a las 11:48


  • @Andy: puede clavar un clavo en una pared con el tacón de su zapato, ¡pero en general preferimos la herramienta adecuada para el trabajo correcto! Lea los documentos de ambos métodos, o simplemente lea mi respuesta a continuación.

    – Jamiec

    16 de febrero de 2016 a las 11:59


  • @Andy: para clavar un clavo en una pared, necesitas un martillo, no un zapato (se aplica el mismo punto)

    – Jamiec

    16 de febrero de 2016 a las 12:01

avatar de usuario
Venkata-raju

push devuelve la nueva longitud de la matriz.

Lo que necesita es la matriz proporcionada inicialmente.

Entonces cambie el código como se muestra a continuación.

var store = [0, 1, 2, 3, 4];

var stored = store.reduce(function(pV, cV, cI){
  console.log("pv: ", pV);
  pV.push(cV);
  return pV; // *********  Important ******
}, []);

concat devuelve la nueva matriz que combina los elementos de la matriz proporcionada y los elementos concatenados. entonces funciona

avatar de usuario
jamiec

Solo para completar, y para la próxima persona que responda a esta pregunta, lo que está haciendo generalmente se logra con map que, como se indica en los documentos

map llama a una función de devolución de llamada proporcionada una vez para cada elemento en una matriz, en orden, y construye una nueva matriz a partir de los resultados

Contraste eso con la descripción de reduce:

El método reduce() aplica una función contra un acumulador y cada valor de la matriz (de izquierda a derecha) para reducirlo a un solo valor.

(Énfasis mío) Así que ya ves, aunque tú pueden manipular reduce para devolver una nueva matriz, su uso general es reducir una matriz a un solo valor.

Entonces, para su código, esto sería:

var store = [0,1,2,3,4];

var stored = store.map(function(pV){
  console.log("pv: ", pV);
  return pV;
});

Mucho más simple que tratar de reconstruir una nueva matriz usando cualquiera push o concat Dentro de un reduce función.

  • A veces, quieres hacer un .filter().map() y en lugar de ser O (2N), puede reducir el trabajo a la mitad haciendo un solo paso usando .reduce()manteniéndote O(N).

    – expediente

    25 de noviembre de 2020 a las 15:23

  • Supongo que con ECMA será algo como store.map(it => {return it});?

    – fedorqui

    30 de noviembre de 2020 a las 11:11

  • @fedorqui’SOstopharming’ store.map(it => ({it})) también funcionará.

    – Jamiec

    30 de noviembre de 2020 a las 11:32

  • ¡Excelente! Si bien creo que iría con la versión con un returnpor lo que es más fácil de entender para mí 🙂

    – fedorqui

    30 de noviembre de 2020 a las 11:34

Sé que esta es la misma respuesta, pero solo quiero mostrar que usando reduce ()la sintaxis también se puede reducir a una sola línea de código usando ES6:

var store = [0,1,2,3,4];

var stored = store.reduce((pV,cV) => [...pV, cV], []);

console.log(stored);

avatar de usuario
un bit de código

reduce() puede ser útil si necesita devolver una matriz con varios elementos para cada elemento iterado:

var inputs = media.reduce((passedArray, video) => {
    passedArray.push("-i");
    passedArray.push(video.filepath);
    return passedArray;
}, []);

Aquí se usa para construir la matriz de entrada para FFmpeg;

[{ name: "bob", filepath: "1.mp4" }, { name: "sue", filepath: "3.mp4" }]
=> ["-i", "1.mp4", "-i", "2.mp4]

avatar de usuario
dfsq

Array.prototype.push método devuelve la nueva longitud de la matriz.

matriz.prototipo.concat El método inserta un nuevo elemento en la matriz y devuelve la matriz para que pueda procesarse más. Esto es lo que debe hacer con reduce: pase la matriz modificada a la siguiente iteración.

  • Pero no es la misma matriz; concat asigna una nueva matriz que es ineficiente.

    – Preguntas de Quolonel

    4 de diciembre de 2017 a las 21:53


Siempre puedes usar la desestructuración:

var store = [0,1,2,3,4];

var stored = store.reduce(function(pV,cV,cI){
  console.log("pv: ", pV);
  return [...pV, cV];
},[]);

console.log(stored);

  • Pero no es la misma matriz; concat asigna una nueva matriz que es ineficiente.

    – Preguntas de Quolonel

    4 de diciembre de 2017 a las 21:53


¿Ha sido útil esta solución?