Практика: работа с данными
Собрали задачи, которые часто встречаются в реальной работе.
Группировка
function groupBy(items, keyFn) {
return items.reduce((acc, item) => {
const key = typeof keyFn === 'function' ? keyFn(item) : item[keyFn];
acc[key] = acc[key] ?? [];
acc[key].push(item);
return acc;
}, {});
}
groupBy(users, 'role');
groupBy(orders, (o) => o.status);
Индексация
function indexBy(items, key) {
return items.reduce((acc, item) => {
acc[item[key]] = item;
return acc;
}, {});
}
const usersById = indexBy(users, 'id');
usersById[1]; // user
Уникальные
const unique = [...new Set(items)];
function uniqueBy(items, key) {
const seen = new Set();
return items.filter((item) => {
const k = typeof key === 'function' ? key(item) : item[key];
if (seen.has(k)) return false;
seen.add(k);
return true;
});
}
Сортировка
const sorted = [...users].sort((a, b) => a.age - b.age);
function sortBy(items, key, dir = 'asc') {
return [...items].sort((a, b) => {
const av = typeof key === 'function' ? key(a) : a[key];
const bv = typeof key === 'function' ? key(b) : b[key];
if (av < bv) return dir === 'asc' ? -1 : 1;
if (av > bv) return dir === 'asc' ? 1 : -1;
return 0;
});
}
Слияние массивов объектов
const merged = [...a, ...b];
const byId = new Map();
for (const item of [...a, ...b]) {
byId.set(item.id, item);
}
const deduped = [...byId.values()];
Обновление по id
const updated = users.map((u) =>
u.id === targetId ? { ...u, name: 'Новое' } : u
);
Удаление по id
const filtered = users.filter((u) => u.id !== targetId);
Вставка в массив
const inserted = [...users.slice(0, index), newUser, ...users.slice(index)];
Перемещение
function move(arr, from, to) {
const copy = [...arr];
const [item] = copy.splice(from, 1);
copy.splice(to, 0, item);
return copy;
}
Подсчёт
const totals = orders.reduce((acc, o) => {
acc[o.userId] = (acc[o.userId] ?? 0) + o.amount;
return acc;
}, {});
Фильтр по нескольким условиям
const filtered = users.filter((u) =>
(!filters.role || u.role === filters.role) &&
(!filters.active || u.active === filters.active) &&
(!filters.search || u.name.toLowerCase().includes(filters.search.toLowerCase()))
);
Пагинация
function paginate(items, page, perPage) {
const start = (page - 1) * perPage;
return {
data: items.slice(start, start + perPage),
total: items.length,
page,
lastPage: Math.ceil(items.length / perPage),
};
}
Сортировка по нескольким полям
const sorted = [...users].sort((a, b) =>
a.lastName.localeCompare(b.lastName) ||
a.firstName.localeCompare(b.firstName)
);
Глубокое обновление
function updateNested(obj, path, value) {
const [head, ...rest] = path;
if (rest.length === 0) return { ...obj, [head]: value };
return {
...obj,
[head]: updateNested(obj[head] ?? {}, rest, value),
};
}
Из массива в дерево
function buildTree(items, parentId = null) {
return items
.filter((item) => item.parentId === parentId)
.map((item) => ({
...item,
children: buildTree(items, item.id),
}));
}
Итоги
groupBy,indexBy,uniqueBy- Сортировка с несколькими полями
- Иммутабельные обновления
Mapдля дедупликации- Вставка через
slice - Рекурсия для дерева