Создать функцию, которая принимает массив чисел и возвращает строку с диапазонами последовательных чисел
Что проверяют
Базовый JavaScript без библиотек и внимание к границам массива. Такая задача часто маскирует настоящий кейс из интерфейса: свернуть номера страниц в пагинации или список выделенных строк таблицы в компактную подпись.
Как отвечать
Уточнить контракт: отсортирован ли вход, бывают ли дубликаты, какой разделитель, что вернуть на пустом массиве. Дальше один проход, заглядывающий на элемент вперёд:
function formatRanges(nums) {
if (nums.length === 0) return "";
const parts = [];
let start = nums[0];
for (let i = 0; i < nums.length; i++) {
if (nums[i + 1] !== nums[i] + 1) {
parts.push(start === nums[i] ? `${start}` : `${start}..${nums[i]}`);
start = nums[i + 1];
}
}
return parts.join(", ");
}На последнем шаге nums[i + 1] даёт undefined, сравнение возвращает false, интервал закрывается сам, и отдельная ветка для хвоста не нужна. Проговорите сложность: один проход, O(n) по времени и O(k) по памяти на список кусков. Если вход не гарантированно отсортирован, сортировать надо копию.
Где спотыкаются
Вызывают sort() без компаратора. В JavaScript сортировка по умолчанию приводит элементы к строкам, поэтому 10 оказывается раньше 9, и диапазоны разъезжаются на двузначных числах. Нужен sort((a, b) => a - b).
Забывают, что sort и reverse меняют исходный массив. Если функция получила массив из состояния компонента или из props, вы мутировали внешние данные: React не увидит изменения по ссылке, и вместо ошибки получится плавающий баг рендера. Копия делается через slice() или spread.
Собирают результат конкатенацией строки в цикле и ловят лишнюю запятую в начале или в конце, а потом чинят это срезом. Надёжнее накопить куски в массиве и один раз склеить через join, заодно пропадает вопрос про хвост.