JavaScript
Tutorial JavaScript: Reducción con reduce()
JavaScript reduce: uso en arrays y ejemplos. Aprende a usar reduce en arrays de JavaScript con ejemplos prácticos y detallados.
Aprende JavaScript y certifícateFundamentos de reduce(): Agregación y transformación de colecciones hacia un único valor
El método reduce()
es una de las herramientas más versátiles y potentes del paradigma de programación funcional en JavaScript. A diferencia de otros métodos de iteración como map()
o filter()
, reduce()
nos permite condensar o "reducir" una colección de valores a un único resultado, lo que lo convierte en una herramienta fundamental para operaciones de agregación y transformación.
Sintaxis básica
La sintaxis básica de reduce()
es la siguiente:
array.reduce(callback(accumulator, currentValue[, index[, array]]), initialValue)
Donde:
- callback: Función que se ejecuta en cada elemento del array
- accumulator: Acumula el valor retornado por la función callback
- currentValue: El elemento actual que está siendo procesado
- index (opcional): Índice del elemento actual
- array (opcional): El array sobre el cual se llamó a reduce()
- initialValue (opcional): Valor inicial del acumulador
Funcionamiento interno
El proceso de reduce()
puede visualizarse como una cadena de transformaciones donde cada paso toma el resultado anterior y lo combina con el siguiente elemento:
- Si se proporciona un
initialValue
, el acumulador comienza con ese valor - Si no se proporciona, el primer elemento del array se usa como acumulador inicial
- La función callback se ejecuta para cada elemento, actualizando el acumulador
- El valor final del acumulador se devuelve como resultado
Ejemplos básicos
Veamos algunos ejemplos fundamentales para entender cómo funciona reduce()
:
- 1. Suma de valores en un array:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15
- 2. Calculando el producto de todos los elementos:
const numbers = [1, 2, 3, 4];
const product = numbers.reduce((accumulator, currentValue) => accumulator * currentValue, 1);
console.log(product); // 24
- 3. Encontrando el valor máximo:
const numbers = [5, 20, 100, 60, 1];
const max = numbers.reduce((max, current) => current > max ? current : max, numbers[0]);
console.log(max); // 100
La importancia del valor inicial
El parámetro initialValue
es crucial en muchas operaciones con reduce()
. Aunque es opcional, omitirlo puede llevar a comportamientos inesperados:
// Con valor inicial
[].reduce((acc, curr) => acc + curr, 0); // Devuelve 0
// Sin valor inicial
[].reduce((acc, curr) => acc + curr); // Error: Reduce of empty array with no initial value
Proporcionar un valor inicial adecuado tiene varias ventajas:
- Evita errores con arrays vacíos
- Define claramente el tipo de dato del resultado
- Mejora la legibilidad del código
- Permite transformaciones entre diferentes tipos de datos
Transformación de tipos
Una característica poderosa de reduce()
es que el acumulador puede ser de un tipo diferente al de los elementos del array:
// Transformando un array de strings a un objeto
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const count = fruits.reduce((countObj, fruit) => {
countObj[fruit] = (countObj[fruit] || 0) + 1;
return countObj;
}, {});
console.log(count); // { apple: 3, banana: 2, orange: 1 }
En este ejemplo, transformamos un array de strings en un objeto que cuenta las ocurrencias de cada fruta.
Encadenamiento con otros métodos de array
reduce()
se puede combinar con otros métodos de array para crear pipelines de procesamiento más complejos:
const orders = [
{ id: 1, items: 3, total: 150 },
{ id: 2, items: 1, total: 50 },
{ id: 3, items: 5, total: 200 }
];
// Calcular el total de ventas para pedidos con más de 2 items
const totalForLargeOrders = orders
.filter(order => order.items > 2)
.reduce((sum, order) => sum + order.total, 0);
console.log(totalForLargeOrders); // 350
Casos de uso comunes
- 1. Aplanar arrays anidados:
const nestedArrays = [[1, 2], [3, 4], [5, 6]];
const flattened = nestedArrays.reduce((acc, curr) => acc.concat(curr), []);
console.log(flattened); // [1, 2, 3, 4, 5, 6]
- 2. Agrupar objetos por una propiedad:
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
{ name: 'Dave', age: 30 }
];
const groupedByAge = people.reduce((groups, person) => {
const age = person.age;
groups[age] = groups[age] || [];
groups[age].push(person);
return groups;
}, {});
console.log(groupedByAge);
// {
// 25: [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
// 30: [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }]
// }
- 3. Eliminar duplicados de un array:
const numbers = [1, 2, 2, 3, 4, 4, 5];
const unique = numbers.reduce((acc, curr) => {
if (!acc.includes(curr)) {
acc.push(curr);
}
return acc;
}, []);
console.log(unique); // [1, 2, 3, 4, 5]
Consideraciones de rendimiento
Aunque reduce()
es muy versátil, hay algunas consideraciones importantes:
- Para operaciones simples en arrays grandes, los bucles tradicionales pueden ser más rápidos
- Evita modificar el acumulador directamente (mutación) para mantener los principios de programación funcional
- Considera usar
reduceRight()
cuando necesites procesar un array de derecha a izquierda
// Ejemplo de reduceRight() para invertir un string
const string = "Hello";
const reversed = Array.from(string).reduceRight((acc, char) => acc + char, "");
console.log(reversed); // "olleH"
Depuración de reducciones
Depurar operaciones complejas con reduce()
puede ser desafiante. Una técnica útil es agregar un console.log
dentro de la función callback:
const result = [1, 2, 3, 4].reduce((acc, curr, idx) => {
console.log(`Iteración ${idx}: acc = ${acc}, curr = ${curr}`);
return acc + curr;
}, 0);
// Muestra:
// Iteración 0: acc = 0, curr = 1
// Iteración 1: acc = 1, curr = 2
// Iteración 2: acc = 3, curr = 3
// Iteración 3: acc = 6, curr = 4
// Resultado final: 10
Este enfoque de visualización paso a paso es invaluable para entender y depurar reducciones complejas.
El método reduce()
es una herramienta fundamental que todo desarrollador JavaScript debería dominar. Su capacidad para transformar colecciones en valores únicos lo convierte en un componente esencial para implementar algoritmos de agregación y transformación de datos de manera elegante y funcional.
Patrones avanzados de reducción: Más allá de las agregaciones numéricas simples
Aunque reduce()
es comúnmente asociado con operaciones numéricas como sumas o promedios, su verdadero potencial se revela cuando lo aplicamos a transformaciones de datos más complejas. En esta sección exploraremos patrones avanzados que demuestran la versatilidad de este método en escenarios reales de desarrollo.
Composición de funciones con reduce()
Uno de los patrones más elegantes es utilizar reduce()
para componer funciones, similar a cómo funcionan las tuberías (pipes) en programación funcional:
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);
// Funciones individuales
const addOne = x => x + 1;
const double = x => x * 2;
const square = x => x * x;
// Componiendo funciones
const transform = compose(square, double, addOne);
console.log(transform(3)); // square(double(addOne(3))) = square(double(4)) = square(8) = 64
Este patrón permite crear transformaciones complejas a partir de funciones simples, mejorando la modularidad y reutilización del código.
Implementación de máquinas de estado
reduce()
puede implementar máquinas de estado finitas, procesando secuencias de eventos y manteniendo un estado interno:
const events = [
{ type: 'LOGIN', user: 'alice' },
{ type: 'ADD_TO_CART', item: 'book', quantity: 1 },
{ type: 'ADD_TO_CART', item: 'laptop', quantity: 1 },
{ type: 'CHECKOUT' },
{ type: 'LOGOUT' }
];
const initialState = { user: null, cart: [], status: 'idle' };
const finalState = events.reduce((state, event) => {
switch (event.type) {
case 'LOGIN':
return { ...state, user: event.user, status: 'active' };
case 'ADD_TO_CART':
return {
...state,
cart: [...state.cart, { item: event.item, quantity: event.quantity }]
};
case 'CHECKOUT':
return { ...state, status: 'completed', cart: [] };
case 'LOGOUT':
return { ...state, user: null, status: 'idle' };
default:
return state;
}
}, initialState);
console.log(finalState);
// { user: null, cart: [], status: 'idle' }
Este patrón es la base conceptual de bibliotecas como Redux, donde el estado de la aplicación evoluciona a través de reducciones sucesivas.
Procesamiento de estructuras de datos anidadas
reduce()
es especialmente útil para procesar estructuras de datos jerárquicas o anidadas:
const fileSystem = {
name: 'root',
files: [
{ name: 'notes.txt', size: 200 },
{ name: 'data.csv', size: 300 }
],
folders: [
{
name: 'projects',
files: [
{ name: 'project1.js', size: 400 },
{ name: 'project2.js', size: 500 }
],
folders: [
{
name: 'legacy',
files: [{ name: 'old.js', size: 100 }],
folders: []
}
]
}
]
};
// Función recursiva para calcular el tamaño total
function calculateSize(item) {
// Tamaño de archivos directos
const filesSize = item.files.reduce((sum, file) => sum + file.size, 0);
// Tamaño de carpetas anidadas (recursión)
const foldersSize = item.folders.reduce((sum, folder) => sum + calculateSize(folder), 0);
return filesSize + foldersSize;
}
console.log(calculateSize(fileSystem)); // 1500
Este patrón permite recorrer y transformar estructuras de datos complejas de manera declarativa y elegante.
Construcción de pipelines de procesamiento
Podemos crear pipelines de procesamiento de datos que apliquen múltiples transformaciones en secuencia:
const pipeline = functions => data => {
return functions.reduce((acc, fn) => fn(acc), data);
};
// Funciones de transformación
const removeEmptyLines = text => text.split('\n').filter(line => line.trim()).join('\n');
const capitalizeFirstLetter = text => text.replace(/^(.)|\n(.)/g, match => match.toUpperCase());
const addTimestamp = text => `[${new Date().toISOString()}]\n${text}`;
// Crear pipeline
const processText = pipeline([
removeEmptyLines,
capitalizeFirstLetter,
addTimestamp
]);
const text = `
hello world
this is a test
`;
console.log(processText(text));
// [2023-11-10T12:34:56.789Z]
// Hello World
// This Is A Test
Este patrón permite descomponer problemas complejos en transformaciones más pequeñas y manejables.
Implementación de promesas encadenadas
reduce()
puede simular el comportamiento de Promise.then()
para operaciones asíncronas secuenciales:
const asyncSequence = (initialValue, asyncFunctions) => {
return asyncFunctions.reduce(
(promise, fn) => promise.then(fn),
Promise.resolve(initialValue)
);
};
// Funciones asíncronas
const fetchUser = async (id) => {
// Simulación de API
return { id, name: `User ${id}` };
};
const fetchPosts = async (user) => {
// Simulación de API
return { ...user, posts: [`Post 1 by ${user.name}`, `Post 2 by ${user.name}`] };
};
const formatData = async (userData) => {
return {
...userData,
postCount: userData.posts.length,
formattedName: userData.name.toUpperCase()
};
};
// Ejecutar secuencia
asyncSequence(1, [fetchUser, fetchPosts, formatData])
.then(result => console.log(result))
.catch(error => console.error(error));
Este patrón permite orquestar operaciones asíncronas de manera limpia y mantenible.
Acumuladores multidimensionales
A veces necesitamos acumular múltiples valores simultáneamente:
const transactions = [
{ type: 'sale', amount: 100, category: 'electronics' },
{ type: 'refund', amount: 20, category: 'electronics' },
{ type: 'sale', amount: 50, category: 'books' },
{ type: 'sale', amount: 30, category: 'books' },
{ type: 'refund', amount: 10, category: 'books' }
];
const summary = transactions.reduce((acc, transaction) => {
const { type, amount, category } = transaction;
// Actualizar totales por tipo
acc.byType[type] = (acc.byType[type] || 0) + amount;
// Actualizar totales por categoría
acc.byCategory[category] = (acc.byCategory[category] || 0) + (type === 'sale' ? amount : -amount);
// Actualizar total general
acc.total += type === 'sale' ? amount : -amount;
return acc;
}, { byType: {}, byCategory: {}, total: 0 });
console.log(summary);
// {
// byType: { sale: 180, refund: 30 },
// byCategory: { electronics: 80, books: 70 },
// total: 150
// }
Este patrón permite calcular múltiples métricas en una sola pasada por los datos, mejorando la eficiencia.
Implementación de algoritmos de agrupación
reduce()
es ideal para implementar algoritmos de agrupación y clasificación:
const students = [
{ name: 'Ana', grade: 85, subject: 'Math' },
{ name: 'John', grade: 70, subject: 'Science' },
{ name: 'Ana', grade: 90, subject: 'Science' },
{ name: 'John', grade: 80, subject: 'Math' }
];
// Agrupar por estudiante y calcular promedio por materia
const studentPerformance = students.reduce((result, { name, grade, subject }) => {
// Inicializar entrada si no existe
if (!result[name]) {
result[name] = { subjects: {}, averageGrade: 0, totalGrades: 0 };
}
// Agregar calificación a la materia
if (!result[name].subjects[subject]) {
result[name].subjects[subject] = { total: 0, count: 0, average: 0 };
}
result[name].subjects[subject].total += grade;
result[name].subjects[subject].count += 1;
result[name].subjects[subject].average =
result[name].subjects[subject].total / result[name].subjects[subject].count;
// Actualizar promedio general
result[name].totalGrades += grade;
result[name].averageGrade = result[name].totalGrades /
Object.values(result[name].subjects).reduce((sum, { count }) => sum + count, 0);
return result;
}, {});
console.log(studentPerformance);
Este patrón permite transformar datos planos en estructuras jerárquicas más útiles para análisis y visualización.
Implementación de funciones curry
reduce()
puede implementar el currying, una técnica de programación funcional que transforma una función con múltiples argumentos en una secuencia de funciones:
const curry = (fn) => {
const arity = fn.length;
return function curried(...args) {
if (args.length >= arity) {
return fn(...args);
}
return (...moreArgs) => {
return curried(...args, ...moreArgs);
};
};
};
// Función normal
const add = (a, b, c) => a + b + c;
// Versión currificada
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
console.log(curriedAdd(1)(2, 3)); // 6
Este patrón permite crear APIs más flexibles y componibles, facilitando la reutilización de código.
Los patrones avanzados de reduce()
demuestran que este método va mucho más allá de simples sumas o promedios. Su capacidad para transformar datos de manera declarativa lo convierte en una herramienta fundamental para implementar algoritmos complejos de manera elegante y mantenible en JavaScript moderno.
Optimización y composición: Estrategias para reducciones eficientes en contextos funcionales
La optimización de operaciones reduce()
va más allá de simplemente escribir código que funcione. En entornos de producción con grandes volúmenes de datos o en sistemas con restricciones de rendimiento, implementar estrategias eficientes puede marcar una diferencia significativa. Veamos cómo podemos mejorar nuestras reducciones y componerlas de manera óptima.
Selección del valor inicial adecuado
La elección del valor inicial no solo afecta la corrección del resultado, sino también el rendimiento:
// Menos eficiente: conversión innecesaria en cada iteración
const sum = [1, 2, 3, 4, 5].reduce((acc, num) => Number(acc) + Number(num));
// Más eficiente: tipo de dato consistente desde el inicio
const optimizedSum = [1, 2, 3, 4, 5].reduce((acc, num) => acc + num, 0);
Cuando el valor inicial coincide con el tipo de resultado esperado, evitamos conversiones de tipo innecesarias en cada iteración.
Minimización de creaciones de objetos
En reducciones que manipulan objetos, la creación frecuente de nuevos objetos puede afectar el rendimiento:
// Menos eficiente: crea un nuevo objeto en cada iteración
const inefficient = data.reduce((acc, item) => {
return { ...acc, [item.id]: item.value };
}, {});
// Más eficiente: modifica el acumulador directamente cuando la inmutabilidad no es crítica
const efficient = data.reduce((acc, item) => {
acc[item.id] = item.value;
return acc;
}, {});
Aunque la inmutabilidad es un principio importante en programación funcional, en casos de rendimiento crítico, puede ser necesario balancear pureza y eficiencia.
Reducción temprana de conjuntos de datos
Cuando sea posible, reduce el tamaño del conjunto de datos antes de aplicar operaciones complejas:
// Menos eficiente: procesa todos los elementos
const result = bigArray
.reduce((acc, item) => {
if (item.value > 1000) {
// Cálculos complejos...
return acc + complexCalculation(item);
}
return acc;
}, 0);
// Más eficiente: filtra primero, reduce después
const optimizedResult = bigArray
.filter(item => item.value > 1000)
.reduce((acc, item) => acc + complexCalculation(item), 0);
Este patrón de "filtrar primero, reducir después" puede mejorar significativamente el rendimiento cuando muchos elementos serían ignorados en la reducción.
Uso de reducciones paralelas
Para conjuntos de datos muy grandes, podemos implementar estrategias de reducción paralela:
// Función para dividir un array en chunks
const chunk = (array, size) => {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
};
// Reducción paralela usando Promise.all
const parallelReduce = async (array, reducer, initialValue, chunkSize = 1000) => {
// Dividir en chunks para procesamiento paralelo
const chunks = chunk(array, chunkSize);
// Reducir cada chunk en paralelo
const results = await Promise.all(
chunks.map(chunk => {
return new Promise(resolve => {
const result = chunk.reduce(reducer, structuredClone(initialValue));
resolve(result);
});
})
);
// Combinar los resultados parciales
return results.reduce((acc, result) => {
// Lógica para combinar resultados parciales
return combineResults(acc, result);
}, initialValue);
};
Esta técnica es especialmente útil cuando:
- El conjunto de datos es muy grande
- La operación de reducción es computacionalmente intensiva
- Las reducciones parciales pueden combinarse fácilmente
Memoización de resultados intermedios
Para cálculos repetitivos, la memoización puede evitar recálculos innecesarios:
// Función para crear un reductor memoizado
const memoizedReducer = (reducer) => {
const cache = new Map();
return (acc, current, index, array) => {
const cacheKey = JSON.stringify(current);
if (cache.has(cacheKey)) {
return reducer(acc, cache.get(cacheKey), index, array);
}
const result = expensiveComputation(current);
cache.set(cacheKey, result);
return reducer(acc, result, index, array);
};
};
// Uso
const efficientSum = data.reduce(memoizedReducer((acc, value) => acc + value), 0);
Esta técnica es particularmente valiosa cuando:
- Los mismos valores aparecen repetidamente en el conjunto de datos
- El cálculo por elemento es costoso
- El conjunto de valores únicos es significativamente menor que el total
Composición de reductores
Podemos crear reductores más complejos componiendo reductores más simples:
// Reductores simples y reutilizables
const sumReducer = (acc, val) => acc + val;
const countReducer = (acc, _) => acc + 1;
const maxReducer = (acc, val) => Math.max(acc, val);
const minReducer = (acc, val) => Math.min(acc, val);
// Combinador de reductores
const combineReducers = (reducers) => {
return (acc, current, index, array) => {
return Object.keys(reducers).reduce((newAcc, key) => {
newAcc[key] = reducers[key](acc[key], current, index, array);
return newAcc;
}, {});
};
};
// Uso combinado
const statsReducer = combineReducers({
sum: sumReducer,
count: countReducer,
max: maxReducer,
min: minReducer
});
const stats = [5, 10, 15, 20, 25].reduce(statsReducer, { sum: 0, count: 0, max: -Infinity, min: Infinity });
console.log(stats); // { sum: 75, count: 5, max: 25, min: 5 }
Este patrón de composición de reductores permite:
- Mayor reutilización de código
- Mejor organización y mantenibilidad
- Cálculo de múltiples estadísticas en una sola pasada
Transductores: composición eficiente de transformaciones
Los transductores representan un concepto avanzado que permite componer transformaciones de manera eficiente:
// Implementación básica de transductores
const map = (f) => (reducer) => (acc, value) => reducer(acc, f(value));
const filter = (predicate) => (reducer) => (acc, value) =>
predicate(value) ? reducer(acc, value) : acc;
// Función para componer transductores
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
// Transductor compuesto
const transducer = compose(
filter(x => x % 2 === 0), // Solo pares
map(x => x * x) // Elevar al cuadrado
);
// Reductor base
const arrayReducer = (acc, value) => {
acc.push(value);
return acc;
};
// Aplicar transductor
const efficientTransform = [1, 2, 3, 4, 5].reduce(
transducer(arrayReducer),
[]
);
console.log(efficientTransform); // [4, 16]
Los transductores ofrecen varias ventajas:
- Eliminan la creación de colecciones intermedias
- Realizan una sola pasada por los datos
- Combinan múltiples operaciones de manera eficiente
Estrategias para conjuntos de datos infinitos o streams
Para trabajar con flujos potencialmente infinitos, podemos implementar reducciones incrementales:
// Reductor incremental que procesa datos por lotes
class IncrementalReducer {
constructor(reducer, initialValue) {
this.reducer = reducer;
this.accumulator = initialValue;
}
// Procesa un nuevo lote de datos
add(batch) {
this.accumulator = batch.reduce(this.reducer, this.accumulator);
return this;
}
// Obtiene el resultado actual
getResult() {
return this.accumulator;
}
}
// Ejemplo de uso con datos que llegan en lotes
const averageCalculator = new IncrementalReducer(
(acc, value) => ({
sum: acc.sum + value,
count: acc.count + 1,
average: (acc.sum + value) / (acc.count + 1)
}),
{ sum: 0, count: 0, average: 0 }
);
// Procesar lotes de datos a medida que llegan
averageCalculator.add([1, 2, 3]);
console.log(averageCalculator.getResult()); // { sum: 6, count: 3, average: 2 }
averageCalculator.add([4, 5]);
console.log(averageCalculator.getResult()); // { sum: 15, count: 5, average: 3 }
Esta técnica es especialmente útil para:
- Procesamiento de streams de datos
- Análisis en tiempo real
- Situaciones donde los datos llegan en lotes o incrementalmente
Optimización de casos específicos
A veces, los casos específicos permiten optimizaciones que no serían posibles en el caso general:
// Caso general
const sum = array.reduce((acc, val) => acc + val, 0);
// Optimización para arrays numéricos
const fastSum = Float64Array.from(array).reduce((acc, val) => acc + val, 0);
Algunas optimizaciones específicas incluyen:
- Uso de arrays tipados para datos numéricos
- Algoritmos especializados para operaciones comunes (suma, promedio, etc.)
- Aprovechamiento de propiedades matemáticas (asociatividad, conmutatividad)
Monitoreo y perfilado de rendimiento
Para optimizaciones basadas en datos reales, implementa mediciones de rendimiento:
const measureReducePerformance = (reducer, array, initialValue, label = 'Reduce operation') => {
console.time(label);
const result = array.reduce(reducer, initialValue);
console.timeEnd(label);
return result;
};
// Comparar diferentes implementaciones
const result1 = measureReducePerformance(
(acc, val) => ({ ...acc, [val.id]: val }),
largeArray,
{},
'Object spread implementation'
);
const result2 = measureReducePerformance(
(acc, val) => {
acc[val.id] = val;
return acc;
},
largeArray,
{},
'Direct mutation implementation'
);
El perfilado sistemático permite:
- Identificar cuellos de botella reales
- Validar optimizaciones con datos concretos
- Tomar decisiones informadas sobre compensaciones
Equilibrio entre legibilidad y rendimiento
La optimización no debe sacrificar excesivamente la claridad del código:
// Altamente optimizado pero difícil de entender
const optimizedButObscure = data.reduce((a, c) => (a[0] += c.v, a[1] = Math.max(a[1], c.v), a), [0, -Infinity]);
// Buen equilibrio entre rendimiento y legibilidad
const balancedApproach = data.reduce((acc, item) => {
acc.sum += item.value;
acc.max = Math.max(acc.max, item.value);
return acc;
}, { sum: 0, max: -Infinity });
Las mejores optimizaciones mantienen un equilibrio razonable entre rendimiento y mantenibilidad.
La optimización de reducciones es tanto un arte como una ciencia. Requiere comprender profundamente el problema, las características de los datos y el contexto de ejecución. Al aplicar estas estrategias de manera juiciosa, podemos crear código que no solo sea elegante y funcional, sino también eficiente y escalable.
Ejercicios de esta lección Reducción con reduce()
Evalúa tus conocimientos de esta lección Reducción con reduce() con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Funciones flecha
Polimorfismo
Array
Transformación con map()
Gestor de tareas con JavaScript
Manipulación DOM
Funciones
Funciones flecha
Async / Await
Creación y uso de variables
Excepciones
Promises
Funciones cierre (closure)
Herencia
Herencia
Estructuras de control
Selección de elementos DOM
Modificación de elementos DOM
Filtrado con filter() y find()
Funciones cierre (closure)
Funciones
Mapas con Map
Reducción con reduce()
Callbacks
Manipulación DOM
Promises
Async / Await
Eventos del DOM
Async / Await
Promises
Filtrado con filter() y find()
Callbacks
Creación de clases y objetos Restaurante
Reducción con reduce()
Filtrado con filter() y find()
Reducción con reduce()
Conjuntos con Set
Herencia de clases
Eventos del DOM
Clases y objetos
Modificación de elementos DOM
Mapas con Map
Introducción a JavaScript
Funciones
Tipos de datos
Clases y objetos
Array
Conjuntos con Set
Array
Encapsulación
Clases y objetos
Uso de operadores
Uso de operadores
Estructuras de control
Excepciones
Transformación con map()
Funciones flecha
Selección de elementos DOM
Encapsulación
Mapas con Map
Creación y uso de variables
Polimorfismo
Tipos de datos
Estructuras de control
Todas las lecciones de JavaScript
Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Javascript
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Funciones Cierre (Closure)
Sintaxis
Arrays Y Métodos
Estructuras De Datos
Conjuntos Con Set
Estructuras De Datos
Mapas Con Map
Estructuras De Datos
Funciones Flecha
Programación Funcional
Filtrado Con Filter() Y Find()
Programación Funcional
Transformación Con Map()
Programación Funcional
Reducción Con Reduce()
Programación Funcional
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Manipulación Dom
Dom
Selección De Elementos Dom
Dom
Modificación De Elementos Dom
Dom
Eventos Del Dom
Dom
Callbacks
Programación Asíncrona
Promises
Programación Asíncrona
Async / Await
Programación Asíncrona
Certificados de superación de JavaScript
Supera todos los ejercicios de programación del curso de JavaScript y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Entender el propósito y uso del método
reduce()
en JavaScript. - Conocer la sintaxis del método
reduce()
y cómo se aplica a un array. - Aprender a definir funciones reductoras que operen sobre los elementos del array y acumulen resultados.
- Comprender el concepto de acumulador y cómo se utiliza en la función reductora.
- Saber cómo proporcionar un valor inicial para el acumulador y cómo afecta el proceso de reducción.
- Conocer ejemplos prácticos de uso del método
reduce()
para calcular sumas, productos, promedios y conteos de elementos en un array. - Comprender la flexibilidad y utilidad del método
reduce()
para adaptarse a diferentes casos de uso en el procesamiento de arrays.