> Как работает функция groupBy в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Яндекс
Стек: JavaScript
> Пример ответа
Короткий ответ
groupBy - это статический метод Object.groupBy, появившийся в ES2024. Он группирует элементы итерируемого объекта по ключу, который возвращает callback-функция. Результат - обычный объект, где ключи - это значения, возвращённые колбэком, а значения - массивы исходных элементов. Метод не мутирует исходный массив и возвращает новый объект. Для Map существует аналогичный Map.groupBy.
Подробное объяснение
Object.groupBy(items, callbackFn) принимает два аргумента:
items- итерируемый объект (массив, Set, строка и т.д.)callbackFn- функция, которая вызывается для каждого элемента и возвращает ключ группы (строку или Symbol)
Колбэк получает три аргумента: текущий элемент, индекс (или ключ для не-массивов) и сам итерируемый объект.
Ключевые особенности:
- Возвращает объект с null-прототипом (без
Object.prototype), что защищает от коллизий с унаследованными свойствами - Порядок ключей в объекте соответствует порядку первого появления группы
- Элементы внутри каждой группы сохраняют исходный порядок
- Не поддерживает
thisArg- в отличие отArray.prototype.mapилиforEach - Если колбэк возвращает
Symbol, он будет использован как ключ, но при обращении через точку это не сработает - только через скобочную нотацию
Map.groupBy работает аналогично, но возвращает Map, что удобно, когда ключи - не строки или нужен гарантированный порядок вставки.
На практике
Типичные сценарии использования:
- Группировка пользователей по ролям или статусу
- Агрегация транзакций по датам или категориям
- Разделение данных на валидные/невалидные
- Кластеризация элементов по вычисляемому признаку
До появления groupBy разработчики использовали reduce с ручной проверкой наличия ключа, что было более многословно и подвержено ошибкам. Метод значительно упрощает код и делает его более декларативным.
Важно помнить: метод доступен в Node.js 21+ и современных браузерах (Chrome 117+, Firefox 119+, Safari 17.4+). Для старых окружений нужен полифилл.
Пример кода
JAVASCRIPTconst users = [{ name: 'Анна', role: 'admin', age: 30 },{ name: 'Борис', role: 'user', age: 25 },{ name: 'Виктор', role: 'admin', age: 35 },{ name: 'Галина', role: 'user', age: 28 },];// Группировка по ролиconst byRole = Object.groupBy(users, user => user.role);// {// admin: [{ name: 'Анна', ... }, { name: 'Виктор', ... }],// user: [{ name: 'Борис', ... }, { name: 'Галина', ... }]// }// Группировка по возрастной категорииconst byAgeGroup = Object.groupBy(users, user => {if (user.age < 30) return 'young';if (user.age < 35) return 'middle';return 'senior';});// С Symbol в качестве ключаconst GROUP = Symbol('group');const grouped = Object.groupBy([1, 2, 3], num => num > 1 ? GROUP : 'small');// { small: [1], [Symbol(group)]: [2, 3] }// Map.groupBy для нестроковых ключейconst byAge = Map.groupBy(users, user => user.age);// Map(3) { 30 => [{...}], 25 => [{...}], 35 => [{...}] }
Как отвечать на собеседовании
Начните с краткого определения и синтаксиса. Затем покажите пример с реальными данными. Упомяните разницу между Object.groupBy и Map.groupBy. Обязательно скажите про null-прототип результата и отсутствие thisArg. Если спросят про альтернативы - покажите реализацию через reduce. Завершите упоминанием поддержки и полифиллов.
Хорошая структура ответа:
- Определение и сигнатура
- Пример использования
- Особенности реализации
- Сравнение с альтернативами
- Ограничения и поддержка
Что проверяет интервьюер
- Понимание современных возможностей языка и их назначения
- Умение объяснить разницу между похожими методами (
Object.groupByvsMap.groupBy) - Знание edge cases: Symbol-ключи, null-прототип, отсутствие
thisArg - Способность предложить альтернативную реализацию через
reduce - Осведомлённость о поддержке в различных окружениях
- Понимание, когда метод уместен, а когда лучше использовать другие структуры данных
Типичные ошибки
- Утверждение, что
groupByмутирует исходный массив - это не так - Забывают, что результат имеет null-прототип, и пытаются вызвать
hasOwnPropertyнапрямую - Путают
Object.groupByсArray.prototype.groupBy(такого метода не существует) - Не упоминают, что колбэк не получает
thisArg - Используют
groupByдля группировки по числовым ключам, не учитывая, что они станут строками в объекте - Предлагают
groupByкак заменуreduceво всех случаях, не учитывая, что для сложной агрегацииreduceгибче - Не знают про
Map.groupByдля случаев, когда нужны нестроковые ключи или гарантированный порядок
> Похожие задачи по frontend
Можно ли пометить стрелочную функцию как асинхронную в JavaScript
Что возвращает метод filter в JavaScript, если ни один элемент не подходит под условие
Как собрать неопределённое количество аргументов функции в JavaScript и работать с ними
Каков порядок выполнения синхронных задач, микротасков и макротасков в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью