Reducir, algo aparentemente común, en realidad es un método muy útil. Mucha gente lo usa más como una herramienta de suma, pero en realidad tiene más usos. Depende de cómo lo usemos. Descubra su uso y hable de ello lentamente a continuación.
reduce() es el método de fusión de la matriz JavaScript Array. Al igual que forEach, map, some, each y otros métodos de iteración, se atravesará cada elemento de la matriz, pero reducir puede operar simultáneamente en los resultados generados al atravesar los elementos de la matriz anterior y el elemento actual Esto es algo que otros métodos iterativos no pueden hacer, lo que le otorga capacidades diferentes.
1. reducir la sintaxis
arr.reduce(function(prev, cur, index, arr) {
......
}, init)
-
arr representa la matriz original;
-
prev representa el valor devuelto la última vez que se llamó a la devolución de llamada, o el valor inicial init. Cuando no se especifica el valor inicial, el valor es el primer elemento de la matriz y cur es el segundo elemento de la matriz en este momento;
-
cur representa el elemento de la matriz que se está procesando actualmente;
-
índice representa el índice del elemento que se está procesando actualmente. Si se especifica init, el índice es 0. Si no se especifica init, el índice es 1;
-
init representa el valor inicial y no tiene requisitos sobre el tipo.
Parece que varias variables son bastante problemáticas, pero de hecho hay dos principales para recordar: prev y cur, y también hay un valor inicial init al que prestar atención.
2. reducir los casos de uso
A continuación, hablemos de los casos de uso de reducir. Por supuesto, no solo existen los siguientes métodos de uso, sino que los siguientes son los más utilizados: los específicos y de nivel superior se pueden ampliar e implementar cuando sea necesario.
1. suma
La primera es, por supuesto, la suma que todos conocemos y que es relativamente sencilla.
var arr = [12, 42, 12, 61, 73, 19]
var sum = arr.reduce(function(prev, cur){
return prev + cur
}, 0)
console.log(sum) // 219
Debido a que se pasa el valor inicial 0, prev es 0 al principio y cur es el primer elemento de la matriz, 12. Después de la suma, el valor es 12 y el valor se devuelve como el anterior de la segunda suma, y luego se combina con el segundo elemento de la matriz. Los términos se suman, luego se devuelven y luego continúan en secuencia, obteniendo finalmente el resultado 219.
Esto es algo pequeño. Aumentemos la dificultad. Requerimos la suma de un determinado atributo en la matriz de objetos.
var goods = [
{type: 'slipper', price: 24},
{type: 'bowl', price: 11},
{type: 'chopsticks', price: 5},
{type: 'plate', price: 9}
]
var sum = goods.reduce(function(prev, cur) {
return prev + cur.price
}, 0)
console.log(sum) // 49
El principio sigue siendo el mismo, pero no olvide dar un valor inicial de 0; de lo contrario, el resultado será [objeto Objeto] 1159, porque anterior es el primer elemento en este momento, que es un objeto. Después de la conversión de tipo, En este momento se llama a valueOf, y el objeto devuelto en sí No es un valor operable. Llamar a toString nuevamente devuelve la cadena del objeto [objeto Objeto], y el resto se convierte en concatenación de cadenas.
El valor inicial también puede ser un objeto.
var sum = goods.reduce(function(prev, cur) {
prev.sum = prev.sum + cur.price
return prev
}, { sum: 0})
console.log(sum) // { sum: 49 }
Se puede ver que no hay ningún requisito para el tipo de valor inicial, siempre que la operación en la función sea correcta y se devuelva el anterior después de la operación.
Las sumas anteriores son todas superposiciones de una sola dimensión. Ahora veamos la superposición de múltiples dimensiones, lo que significa que implica la suma de múltiples atributos en lugar de simplemente la suma de un atributo. Ahora cambiemos los requisitos de los casos de uso anteriores. Si hay una tabla de descuentos de productos para varios eventos, ahora necesitamos calcular el precio total de los productos bajo cada descuento.
var goods = [
{type: 'slipper', price: 24},
{type: 'bowl', price: 11},
{type: 'chopsticks', price: 5},
{type: 'plate', price: 9}
]
var discount = {
dis1: 0.6,
dis2: 0.7,
dis3: 0.8
}
var initialState = {
dis1Total: 0,
dis2Total: 0,
dis3Total: 0
}
var sum = goods.reduce(function(outerPrev, outerCur) {
return Object.keys(discount).reduce(function(innerPrev, innerCur) {
outerPrev[`${innerCur}Total`] += outerCur.price*discount[innerCur]
return outerPrev
}, {})
}, initialState )
console.log(sum) // {dis1Total: 29.4, dis2Total: 34.3, dis3Total: 39.2}
De hecho, se siente un poco como agregar un bucle dentro del cuerpo del bucle, lo cual es bastante fácil de entender una vez que lo comprendes.
2. Encuentre el mejor valor
Reducir también se puede utilizar para encontrar el valor máximo o mínimo de una matriz numérica. A continuación se utiliza el valor máximo como ejemplo.
var arr = [12, 42, 12, 61, 73, 19]
var max = arr.reduce((prev, cur) => {
return prev > cur ? prev : cur
})
console.log(max) // 73
Como no se proporciona ningún valor inicial, prev es el primer elemento 12. En la primera ronda de comparación, 12 <42, por lo que el valor de prev después de la primera ronda y se devuelve es 42. Después de eso, el valor máximo es 73.
3. Eliminar la duplicación
reducir también se puede utilizar para eliminar elementos duplicados de una matriz
var arr = [12, 42, 12, 61, 73, 12, 42, 13, 19]
var result = arr.reduce(function(prev, cur){
prev.indexOf(cur) === -1 ? && prev.push(cur)
return prev
},[])
console.log(result) // [12, 42, 61, 73, 13, 19]
Lo anterior establece que el valor inicial es una matriz vacía. Cada vez que se juzga si el elemento actual está en la matriz, si lo está, no se realiza ninguna operación y se devuelve la matriz original. Si no, el elemento se coloca en prev, y finalmente se obtiene una matriz no duplicada.
El mismo principio también se puede utilizar en cadenas para eliminar caracteres repetidos en la cadena y obtener una nueva cadena sin caracteres repetidos.
var str = 'asdaadasfdsdfaderhrrtjsfb'
var result = str.split('').reduce(function(prev, cur) {
prev += prev.indexOf(cur) === -1 ? cur : ''
return prev
}, '')
console.log(result) // asdferhtjb
Por supuesto, también puede lograr la deduplicación de matrices de objetos.
var goods = [{type: 'plate', No: 123}, {type: 'bowl', No: 321}, {type: 'plate', No: 123}]
var result = goods.reduce((prev, cur) => {
if(!prev.some(item => item.No === cur.No)) {
prev.push(cur)
}
return prev
}, [])
console.log(result) // [{type: plate, No: 123}, {type: bowl, No: 321}]
4. Encuentra el número de veces
Reducir se puede utilizar para calcular el resultado del recorrido anterior y el siguiente elemento. También podemos encontrar el número de veces que aparece un elemento o carácter en una matriz o cadena. El siguiente es un ejemplo de cómo encontrar el número de veces que aparece un carácter en un cadena.
var str = 'asfasdasghsfadasdfsdgasdafgsada'
var result = str.split('').reduce((prev, cur) => {
prev[cur] ? prev[cur]++ : prev[cur] = 1
return prev
}, {})
console.log(result) // {a: 9, s: 8, f: 4, d: 6, g: 3, h: 1, s: 8 }
Encontrar el número de apariciones de un elemento en una matriz es lo mismo que arriba.
5. Conversión de tipo
Matriz para objetar
var goods = [{type: 'plate', No: 123}, {type: 'bowl', No: 321}]
var result = goods.reduce((prev, cur) => {
!prev[cur.No] && (prev[cur.No] = cur)
return prev
}, {})
console.log(result ) // {123: {type: "plate", No: 123}, 321: {type: "bowl", No: 321}}
Objeto a matriz
var obj = {123: {type: "plate", No: 123}, 321: {type: "bowl", No: 321}}
var result = Object.keys(obj).reduce((prev, cur) => {
prev.push(obj[cur])
return prev
}, [])
console.log(result) // [{type: "plate", No: 123}, {type: "bowl", No: 321}}]
Por supuesto, esto parece un poco de mal gusto, pero aquí simplemente afirma que tiene la capacidad de lograrlo.
Bien, aquí estamos básicamente familiarizados con los usos comunes de reducir como se enumeran anteriormente. De hecho, mientras aprendamos a adaptarnos, también podemos desarrollar más habilidades de uso. Es solo una cuestión de costo y calidad del método. JS está en constante cambio, podemos tener más opciones.
La siguiente es mi cuenta pública, que está dedicada a impulsar algunos resúmenes del front-end y otros conocimientos, si está interesado, preste atención.