Pregunta

Estoy tratando de decidir si usar el método Reduce () en JavaScript para una función que necesito escribir, que es algo como esto

var x = [some array], y = {};
for (...) {
    someOperation(x[i]);
    y[x[i]] = "some other value";
}

Ahora, esto obviamente se puede escribir como una función Reder () de la siguiente manera:

x.reduce(function(prev, current, index, arr) {
    someOperation(current);
    prev[current] = "some other value";
    return prev;
}, {})

O algo así. ¿Hay algún rendimiento u otra diferencia entre los dos? ¿O alguna otra razón (como el soporte del navegador, por ejemplo) debido a cuál debe ser favorecido sobre el otro en un entorno de programación web? Gracias.

¿Fue útil?

Solución

Aunque prefiero estas operaciones (reducir, mapear, filtrar, etc.), todavía no es factible usarlas debido a cierto navegadores que no los apoyan en sus implementaciones. Claro, puedes "parchearlo" extendiendo el Array Prototipo, pero eso también está abriendo una lata de gusanos.

No creo que haya nada inherentemente malo en estas funciones, y creo que hacen un mejor código, pero por ahora es mejor no usarlas. Una vez que un porcentaje más alto de la población usa un navegador que respalda estas funciones, creo que serán un juego justo.

En cuanto al rendimiento, estos probablemente serán más lentos que las manos escritas para bucles debido a la sobrecarga de las llamadas de funciones.

Otros consejos

map y filter y reduce y forEach y ... (más información: https://developer.mozilla.org/en/javascript/reference/global_objects/array#iteration_methods ) son mucho mejores que los bucles normales porque:

  1. Son más elegantes
  2. Fomentan la programación funcional (ver beneficios de la programación funcional)
  3. Necesitará escribir funciones de todos modos y pasar a ellas, como parámetros, variables de iteración. Esto se debe a que JavaScript no tiene alcance de bloque. Funciones como map y reduce Haga su trabajo mucho más fácil porque configuran automáticamente su variable de iteración y lo pasan a su función por usted.

IE9 afirma apoyarlos. Están en la especificación oficial de JavaScript/Ecmascript. Si te preocupas por las personas que usan IE8, esa es tu prerrogativa. Si realmente te importa, puedes hackearlo anulando Array.prototype Solo para IE8 y más, para "arreglar" IE8 y más.

La reducción se usa para devolver un valor de una matriz, como resultado del procesamiento secuencial de los resultados de los elementos anteriores.

Reduceright hace lo mismo, pero comienza al final y trabaja hacia atrás.

El mapa se usa para devolver una matriz cuyos miembros se han pasado por una función.

Ninguno de los métodos afecta la matriz en sí.

var a1 = ['1', '2', '3', '4', '5', '6', '7', '8'];

// Este uso del mapa devuelve una nueva matriz de los elementos originales, convertido a números-

A1 = a1.map (número); // >> Cada uno de los elementos de A1 se convirtió a un número

// Esto reduce el total de los elementos de la matriz-

var a1sum = a1.reduce (función (a, b) {return a+b;});

// a1sum >> valor devuelto: (número) 36

No son compatibles con los navegadores más antiguos, por lo que deberá proporcionarlos un sustituto. No vale la pena si todo lo que está haciendo puede replicarse en un bucle simple.

Sensar la desviación estándar de una población es un ejemplo en el que tanto el mapa como la reducción pueden usarse efectivamente.

Math.mean= function(array){
    return array.reduce(function(a, b){ return a+b; })/array.length;
}
Math.stDeviation=function(array){
    var mean= Math.mean(array);
    dev= array.map(function(itm){return (itm-mean)*(itm-mean); });
    return Math.sqrt(dev.reduce(function(a, b){ return a+b; })/array.length);
}


var A2= [6.2, 5, 4.5, 6, 6, 6.9, 6.4, 7.5];
alert ('mean: '+Math.mean(A2)+'; deviation: '+Math.stDeviation(A2))

Kennebec - bien, pero tu stdeviación Llamadas de funciones reducir dos veces y mapa una vez cuando solo necesita una sola llamada a reducir (lo que lo hace mucho más rápido):

Math.stDev = function (a) {
    var n = a.length;
    var v = a.reduce(function (v, x) {
      v[0] += x * x;
      v[1] += x;
      return v;
    }, [0,0]);
    return Math.sqrt( (v[0] - v[1]*v[1] / n) / n );
}

Debe hacer una conversión al número al asignar a V [1 Para asegurarse de que los números de cadena no se metan con el resultado y el divisor en la última línea debería ser probable (n - 1) en la mayoría de los casos, pero eso depende de la OP. :-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top