Сортировка и фильтрация массива
Паттерны фильтрации, поиска и сортировки массива объектов — готовые сниппеты для таблиц, каталогов и списков.
Задача
Нужно отображать список товаров/пользователей с возможностью фильтрации по полю, поиска по тексту и сортировки по колонке — без сторонних библиотек.
Решение
const products = [
{ id: 1, name: 'Ноутбук', category: 'electronics', price: 80000, rating: 4.5 },
{ id: 2, name: 'Футболка', category: 'clothing', price: 1500, rating: 4.1 },
{ id: 3, name: 'Смартфон', category: 'electronics', price: 60000, rating: 4.8 },
{ id: 4, name: 'Джинсы', category: 'clothing', price: 3500, rating: 3.9 },
{ id: 5, name: 'Планшет', category: 'electronics', price: 40000, rating: 4.3 },
];
// === ФИЛЬТРАЦИЯ ===
// По категории
const electronics = products.filter((p) => p.category === 'electronics');
// По диапазону цены
const affordable = products.filter((p) => p.price >= 1000 && p.price <= 50000);
// Текстовый поиск по названию
function search(items, query) {
const q = query.toLowerCase().trim();
return q ? items.filter((p) => p.name.toLowerCase().includes(q)) : items;
}
// Несколько фильтров одновременно
function applyFilters(items, { category, minPrice, maxPrice, query }) {
return items
.filter((p) => !category || p.category === category)
.filter((p) => !minPrice || p.price >= minPrice)
.filter((p) => !maxPrice || p.price <= maxPrice)
.filter((p) => !query || p.name.toLowerCase().includes(query.toLowerCase()));
}
const filtered = applyFilters(products, {
category: 'electronics',
maxPrice: 70000,
query: '',
});
// === СОРТИРОВКА ===
// По цене (по возрастанию)
const byPriceAsc = [...products].sort((a, b) => a.price - b.price);
const byPriceDesc = [...products].sort((a, b) => b.price - a.price);
// По строке (локализованная)
const byName = [...products].sort((a, b) => a.name.localeCompare(b.name, 'ru'));
// Универсальная сортировка по ключу
function sortBy(items, key, direction = 'asc') {
return [...items].sort((a, b) => {
const va = a[key];
const vb = b[key];
if (typeof va === 'string') {
const cmp = va.localeCompare(vb, 'ru');
return direction === 'asc' ? cmp : -cmp;
}
return direction === 'asc' ? va - vb : vb - va;
});
}
const sorted = sortBy(products, 'rating', 'desc');
Полный пайплайн фильтр + сортировка:
function processItems(items, filters, sortKey, sortDir) {
const filtered = applyFilters(items, filters);
return sortBy(filtered, sortKey, sortDir);
}
Ключевые моменты
[...products].sort()— всегда копируй массив (spreadилиslice); нативныйsortмутирует оригинал.localeCompare('ru')— правильная сортировка кириллицы; без него буква «Я» окажется перед «А».- Цепочка
.filter.filter— читаема и легко расширяема; производительность приемлема до ~10k элементов. - Для больших массивов (100k+) рассмотри Web Worker или серверную сортировку.
Варианты
Array.prototype.toSorted(ES2023) — возвращает новый отсортированный массив без мутации.Intl.Collator— быстрееlocaleCompareпри многократной сортировке больших массивов.