В дашборде аналитики Shopify нужно: отфильтровать заказы за месяц, посчитать общую выручку, найти топ-3 товара по продажам. Всё это — методы массивов в цепочке.
Мы уже знаем map, filter, find из урока 08. Теперь разберём более мощные инструменты, которые используются в аналитике и сложной обработке данных.
В реальных проектах данные нужно не просто перебирать, но и агрегировать (суммировать, группировать), проверять наличие условий, сортировать. Методы массивов делают это декларативно — описываешь ЧТО хочешь, а не КАК это сделать.
Самый мощный и гибкий метод. Превращает массив в что угодно: число, строку, объект.
const prices = [100, 250, 80, 420]
// Сумма
const total = prices.reduce((accumulator, current) => accumulator + current, 0)
// 0 → 100 → 350 → 430 → 850
console.log(total) // 850
// accumulator (acc) — накопитель, начинается с начального значения (0)
// current — текущий элемент массиваReduce может создавать объекты и группировать данные:
const orders = [
{ status: 'done', amount: 100 },
{ status: 'pending', amount: 200 },
{ status: 'done', amount: 150 },
]
const byStatus = orders.reduce((acc, order) => {
acc[order.status] = (acc[order.status] || 0) + order.amount
return acc
}, {})
// { done: 250, pending: 200 }const cartItems = [
{ name: 'Молоко', inStock: true },
{ name: 'Хлеб', inStock: true },
{ name: 'Масло', inStock: false },
]
// some — хотя бы один элемент удовлетворяет условию?
const hasOutOfStock = cartItems.some(item => !item.inStock)
console.log(hasOutOfStock) // true (масло недоступно)
// every — все элементы удовлетворяют условию?
const allAvailable = cartItems.every(item => item.inStock)
console.log(allAvailable) // falseВажно: sort изменяет исходный массив! И по умолчанию сортирует как строки.
const nums = [10, 2, 30, 1]
nums.sort() // [1, 10, 2, 30] — строковая сортировка! Неверно
nums.sort((a, b) => a - b) // [1, 2, 10, 30] — числовая по возрастанию
nums.sort((a, b) => b - a) // [30, 10, 2, 1] — по убыванию
// Сортировка объектов
products.sort((a, b) => a.price - b.price) // по цене
products.sort((a, b) => b.rating - a.rating) // по рейтингу (убывание)Методы можно вызывать последовательно — каждый следующий работает с результатом предыдущего:
const result = products
.filter(p => p.inStock) // оставляем доступные
.sort((a, b) => a.price - b.price) // сортируем по цене
.slice(0, 5) // берём первые 5
.map(p => p.name) // берём только названияОшибка 1: Забыть начальное значение в reduce
const nums = [1, 2, 3]
nums.reduce((acc, n) => acc + n) // 6 — работает, но опасно
nums.reduce((acc, n) => acc + n, 0) // 6 — правильно, явное начало
// Для пустого массива без начального значения будет ошибка!
[].reduce((acc, n) => acc + n) // TypeError!
[].reduce((acc, n) => acc + n, 0) // 0 — безопасноОшибка 2: Мутировать массив при sort без копирования
const products = [{ price: 100 }, { price: 50 }]
products.sort((a, b) => a.price - b.price) // меняет исходный массив!
// Безопасно:
const sorted = [...products].sort((a, b) => a.price - b.price)Ошибка 3: Сортировать числа без функции сравнения
[10, 9, 100].sort() // [10, 100, 9] — строковая сортировка!
[10, 9, 100].sort((a, b) => a - b) // [9, 10, 100] — правильноЦепочки методов массивов — это основа работы с данными на фронтенде. Redux selectors, Vue computed properties, фильтры каталога, аналитические дашборды — везде используется комбинация filter + map + reduce.
Аналитика продаж для дашборда
const sales = [
{ product: 'Ноутбук', amount: 75000, month: 'Jan', category: 'tech' },
{ product: 'Мышь', amount: 1500, month: 'Jan', category: 'tech' },
{ product: 'Стол', amount: 12000, month: 'Feb', category: 'furniture' },
{ product: 'Монитор', amount: 25000, month: 'Feb', category: 'tech' },
{ product: 'Кресло', amount: 18000, month: 'Jan', category: 'furniture' },
{ product: 'Наушники', amount: 8000, month: 'Feb', category: 'tech' },
]
// Общая выручка от tech в январе
const techJanRevenue = sales
.filter(s => s.category === 'tech' && s.month === 'Jan')
.reduce((sum, s) => sum + s.amount, 0)
console.log('Tech/Jan:', techJanRevenue) // 76500
// Топ-3 продажи по убыванию суммы
const top3 = [...sales]
.sort((a, b) => b.amount - a.amount)
.slice(0, 3)
.map(s => s.product)
console.log('Топ-3:', top3) // ['Ноутбук', 'Монитор', 'Кресло']
// Группировка выручки по категориям
const revenueByCategory = sales.reduce((acc, s) => {
acc[s.category] = (acc[s.category] || 0) + s.amount
return acc
}, {})
console.log(revenueByCategory)
// { tech: 109500, furniture: 30000 }
// Есть ли продажи дороже 50000?
const hasHighValue = sales.some(s => s.amount > 50000)
console.log('Есть крупные продажи:', hasHighValue) // trueВ дашборде аналитики Shopify нужно: отфильтровать заказы за месяц, посчитать общую выручку, найти топ-3 товара по продажам. Всё это — методы массивов в цепочке.
Мы уже знаем map, filter, find из урока 08. Теперь разберём более мощные инструменты, которые используются в аналитике и сложной обработке данных.
В реальных проектах данные нужно не просто перебирать, но и агрегировать (суммировать, группировать), проверять наличие условий, сортировать. Методы массивов делают это декларативно — описываешь ЧТО хочешь, а не КАК это сделать.
Самый мощный и гибкий метод. Превращает массив в что угодно: число, строку, объект.
const prices = [100, 250, 80, 420]
// Сумма
const total = prices.reduce((accumulator, current) => accumulator + current, 0)
// 0 → 100 → 350 → 430 → 850
console.log(total) // 850
// accumulator (acc) — накопитель, начинается с начального значения (0)
// current — текущий элемент массиваReduce может создавать объекты и группировать данные:
const orders = [
{ status: 'done', amount: 100 },
{ status: 'pending', amount: 200 },
{ status: 'done', amount: 150 },
]
const byStatus = orders.reduce((acc, order) => {
acc[order.status] = (acc[order.status] || 0) + order.amount
return acc
}, {})
// { done: 250, pending: 200 }const cartItems = [
{ name: 'Молоко', inStock: true },
{ name: 'Хлеб', inStock: true },
{ name: 'Масло', inStock: false },
]
// some — хотя бы один элемент удовлетворяет условию?
const hasOutOfStock = cartItems.some(item => !item.inStock)
console.log(hasOutOfStock) // true (масло недоступно)
// every — все элементы удовлетворяют условию?
const allAvailable = cartItems.every(item => item.inStock)
console.log(allAvailable) // falseВажно: sort изменяет исходный массив! И по умолчанию сортирует как строки.
const nums = [10, 2, 30, 1]
nums.sort() // [1, 10, 2, 30] — строковая сортировка! Неверно
nums.sort((a, b) => a - b) // [1, 2, 10, 30] — числовая по возрастанию
nums.sort((a, b) => b - a) // [30, 10, 2, 1] — по убыванию
// Сортировка объектов
products.sort((a, b) => a.price - b.price) // по цене
products.sort((a, b) => b.rating - a.rating) // по рейтингу (убывание)Методы можно вызывать последовательно — каждый следующий работает с результатом предыдущего:
const result = products
.filter(p => p.inStock) // оставляем доступные
.sort((a, b) => a.price - b.price) // сортируем по цене
.slice(0, 5) // берём первые 5
.map(p => p.name) // берём только названияОшибка 1: Забыть начальное значение в reduce
const nums = [1, 2, 3]
nums.reduce((acc, n) => acc + n) // 6 — работает, но опасно
nums.reduce((acc, n) => acc + n, 0) // 6 — правильно, явное начало
// Для пустого массива без начального значения будет ошибка!
[].reduce((acc, n) => acc + n) // TypeError!
[].reduce((acc, n) => acc + n, 0) // 0 — безопасноОшибка 2: Мутировать массив при sort без копирования
const products = [{ price: 100 }, { price: 50 }]
products.sort((a, b) => a.price - b.price) // меняет исходный массив!
// Безопасно:
const sorted = [...products].sort((a, b) => a.price - b.price)Ошибка 3: Сортировать числа без функции сравнения
[10, 9, 100].sort() // [10, 100, 9] — строковая сортировка!
[10, 9, 100].sort((a, b) => a - b) // [9, 10, 100] — правильноЦепочки методов массивов — это основа работы с данными на фронтенде. Redux selectors, Vue computed properties, фильтры каталога, аналитические дашборды — везде используется комбинация filter + map + reduce.
Аналитика продаж для дашборда
const sales = [
{ product: 'Ноутбук', amount: 75000, month: 'Jan', category: 'tech' },
{ product: 'Мышь', amount: 1500, month: 'Jan', category: 'tech' },
{ product: 'Стол', amount: 12000, month: 'Feb', category: 'furniture' },
{ product: 'Монитор', amount: 25000, month: 'Feb', category: 'tech' },
{ product: 'Кресло', amount: 18000, month: 'Jan', category: 'furniture' },
{ product: 'Наушники', amount: 8000, month: 'Feb', category: 'tech' },
]
// Общая выручка от tech в январе
const techJanRevenue = sales
.filter(s => s.category === 'tech' && s.month === 'Jan')
.reduce((sum, s) => sum + s.amount, 0)
console.log('Tech/Jan:', techJanRevenue) // 76500
// Топ-3 продажи по убыванию суммы
const top3 = [...sales]
.sort((a, b) => b.amount - a.amount)
.slice(0, 3)
.map(s => s.product)
console.log('Топ-3:', top3) // ['Ноутбук', 'Монитор', 'Кресло']
// Группировка выручки по категориям
const revenueByCategory = sales.reduce((acc, s) => {
acc[s.category] = (acc[s.category] || 0) + s.amount
return acc
}, {})
console.log(revenueByCategory)
// { tech: 109500, furniture: 30000 }
// Есть ли продажи дороже 50000?
const hasHighValue = sales.some(s => s.amount > 50000)
console.log('Есть крупные продажи:', hasHighValue) // trueТы разрабатываешь аналитику для магазина. Используй методы массивов: найди среднюю цену товаров в наличии (inStock: true). Цепочка: filter → map → reduce, потом раздели на количество.
filter(p => p.inStock), затем map(p => p.price), затем reduce((sum, price) => sum + price, 0)