Есть ли в JavaScript метод, аналогичный "range()", для генерации диапазона в заданных границах?
Описание проблемы:
В PHP есть функция range()
, которая позволяет получать диапазон чисел или символов, передавая нижнюю и верхнюю границы. Например:
range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")
Однако, существует ли встроенная функция, аналогичная range()
, в чистом JavaScript? Если такой функции нет, каким образом можно реализовать подобный функционал?
5 ответ(ов)
Вот моё мнение по этому вопросу:
function range(start, end) {
return Array.apply(0, Array(end - start))
.map((element, index) => index + start);
}
В этом коде используется метод Array.apply()
для создания массива длиной end - start
, а затем с помощью map()
каждый элемент заполняется значениями, начиная с start
и заканчивая end - 1
. Обратите внимание, что я изменил end - 1
на end - start
, чтобы правильно заполнить массив. Такой подход позволяет вам создавать последовательность чисел от start
до end - 1
, но я бы рекомендовал также рассмотреть более простые способы создания диапазона, например, с использованием цикла или метода Array.from()
для более понятного кода.
Да, в JavaScript действительно нет функции range()
, как в PHP, поэтому нам нужно создать эту функцию. Это довольно просто, я напишу несколько однострочных функций для вас и разделю их на числовые и алфавитные диапазоны.
Для чисел:
function numberRange(start, end) {
return new Array(end - start).fill().map((d, i) => i + start);
}
Вызывайте её так:
numberRange(5, 10); //[5, 6, 7, 8, 9]
Для алфавитов:
function alphabetRange(start, end) {
return new Array(end.charCodeAt(0) - start.charCodeAt(0)).fill().map((d, i) => String.fromCharCode(i + start.charCodeAt(0)));
}
И вызывайте её так:
alphabetRange('c', 'h'); //["c", "d", "e", "f", "g"]
Если у вас есть дополнительные вопросы или вам нужно что-то конкретное, не стесняйтесь задавать их!
Функция Array.range
создает массив значений в заданном диапазоне. Давайте разберем, как она работает.
Array.range = function(a, b, step){
var A = [];
if(typeof a == 'number'){
A[0] = a; // Начинаем массив с первого элемента 'a'
step = step || 1; // Если шаг не задан, используем 1 как значение по умолчанию
while(a + step <= b){ // Пока текущее значение 'a' плюс шаг не больше 'b'
A[A.length]= a += step; // Увеличиваем 'a' на шаг и добавляем в массив
}
}
else {
var s = 'abcdefghijklmnopqrstuvwxyz'; // Строка со всеми строчными буквами
if(a === a.toUpperCase()){ // Проверяем, если 'a' в верхнем регистре
b = b.toUpperCase(); // Приводим 'b' к верхнему регистру
s = s.toUpperCase(); // Приводим строку к верхнему регистру
}
s = s.substring(s.indexOf(a), s.indexOf(b) + 1); // Извлекаем подстроку от 'a' до 'b'
A = s.split(''); // Превращаем подстроку в массив
}
return A; // Возвращаем получившийся массив
}
Примеры использования:
Array.range(0, 10);
- Возвращает массив с числами от 0 до 10:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
.
- Возвращает массив с числами от 0 до 10:
Array.range(-100, 100, 20);
- Возвращает массив с шагом 20 в диапазоне от -100 до 100:
[-100, -80, -60, -40, -20, 0, 20, 40, 60, 80, 100]
.
- Возвращает массив с шагом 20 в диапазоне от -100 до 100:
Array.range('A', 'F');
- Возвращает массив букв в диапазоне от 'A' до 'F':
['A', 'B', 'C', 'D', 'E', 'F']
.
- Возвращает массив букв в диапазоне от 'A' до 'F':
Array.range('m', 'r');
- Возвращает массив букв от 'm' до 'r':
['m', 'n', 'o', 'p', 'q', 'r']
.
- Возвращает массив букв от 'm' до 'r':
Таким образом, данная функция универсальна и может работать как с числами, так и с буквами, в зависимости от переданных ей аргументов.
Вот перевод на русский язык, стилизованный как ответ на вопрос на StackOverflow:
С диапазоном/шагом
Самый компактный вариант в одну строку:
[...Array(N)].map((_, i) => from + i * step);
Примеры и альтернативы
[...Array(10)].map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array.from(Array(10)).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array.from(Array(10).keys()).map(i => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
[...Array(10).keys()].map(i => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Array(10).fill(0).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array(10).fill().map((_, i) => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Функция диапазона
const range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
range(0, 9, 2);
//=> [0, 2, 4, 6, 8]
// Также можно добавить функцию range в класс Array (но это не рекомендуется)
Array.range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
Array.range(2, 10, 2);
//=> [2, 4, 6, 8, 10]
Array.range(0, 10, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Array.range(2, 10, -1);
//=> []
Array.range(3, 0, -1);
//=> [3, 2, 1, 0]
В виде итераторов
class Range {
constructor(total = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
for (let i = 0; i < total; yield from + i++ * step) {}
};
}
}
[...new Range(5)]; // Пять элементов
//=> [0, 1, 2, 3, 4]
[...new Range(5, 2)]; // Пять элементов с шагом 2
//=> [0, 2, 4, 6, 8]
[...new Range(5, -2, 10)]; // Пять элементов с шагом -2 начиная с 10
//=>[10, 8, 6, 4, 2]
[...new Range(5, -2, -10)]; // Пять элементов с шагом -2 начиная с -10
//=> [-10, -12, -14, -16, -18]
// Также работает с циклом for..of
for (i of new Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
Только генераторы
const Range = function* (total = 0, step = 1, from = 0) {
for (let i = 0; i < total; yield from + i++ * step) {}
};
Array.from(Range(5, -2, -10));
//=> [-10, -12, -14, -16, -18]
[...Range(5, -2, -10)]; // Пять элементов с шагом -2 начиная с -10
//=> [-10, -12, -14, -16, -18]
// Также работает с циклом for..of
for (i of Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
// Ленивый способ
const number0toInf = Range(Infinity);
number0toInf.next().value;
//=> 0
number0toInf.next().value;
//=> 1
// ...
С диапазоном и шагами/дельтой
Используя итераторы:
class Range2 {
constructor(to = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
}
}
[...new Range2(5)]; // Первые 5 целых чисел
//=> [0, 1, 2, 3, 4]
[...new Range2(5, 2)]; // От 0 до 5 с шагом 2
//=> [0, 2, 4]
[...new Range2(5, -2, 10)]; // От 10 до 5 с шагом -2
//=> [10, 8, 6]
Используя генераторы:
const Range2 = function* (to = 0, step = 1, from = 0) {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
[...Range2(5, -2, 10)]; // От 10 до 5 с шагом -2
//=> [10, 8, 6]
let even4to10 = Range2(10, 2, 4);
even4to10.next().value;
//=> 4
even4to10.next().value;
//=> 6
even4to10.next().value;
//=> 8
even4to10.next().value;
//=> 10
even4to10.next().value;
//=> undefined
Для TypeScript
class _Array<T> extends Array<T> {
static range(from: number, to: number, step: number): number[] {
return Array.from(Array(Math.floor((to - from) / step) + 1)).map(
(v, k) => from + k * step
);
}
}
_Array.range(0, 9, 1);
Генерация списка символов в одну строку
const charList = (a,z,d=1)=>(a=a.charCodeAt(),z=z.charCodeAt(),[...Array(Math.floor((z-a)/d)+1)].map((_,i)=>String.fromCharCode(a+i*d)));
console.log("от A до G", charList('A', 'G'));
console.log("от A до Z с шагом 2", charList('A', 'Z', 2));
console.log("в обратном порядке от Z до P", charList('Z', 'P', -1));
console.log("от 0 до 5", charList('0', '5', 1));
console.log("от 9 до 5", charList('9', '5', -1));
console.log("от 0 до 8 с шагом 2", charList('0', '8', 2));
console.log("от α до ω", charList('α', 'ω'));
console.log("индийские символы от क до ह", charList('क', 'ह'));
console.log("русские символы от А до Я", charList('А', 'Я'));
Для TypeScript:
const charList = (p: string, q: string, d = 1) => {
const a = p.charCodeAt(0),
z = q.charCodeAt(0);
return [...Array(Math.floor((z - a) / d) + 1)].map((_, i) =>
String.fromCharCode(a + i * d)
);
};
В данном коде создаётся функция range
, которая принимает два аргумента l
и r
. Она возвращает массив, содержащий последовательные числа от l
до r - 1
. Вот как работает данный код:
new Array(r - l)
— создаёт новый массив длиной, равной разнице междуr
иl
..fill()
— заполняет созданный массив "пустыми" значениями, чтобы методmap
мог быть применён..map((_, k) => k + l)
— использует методmap
для преобразования каждого элемента массива. Здесь переменная_
представляет текущее значение (мы её не используем), аk
— индекс, который будет от 0 доr-l-1
. Мы добавляемl
к индексу, чтобы получить нужные значения.
Пример использования функции:
console.log(range(3, 7)); // Выведет [3, 4, 5, 6]
Таким образом, функция range(l, r)
эффективно генерирует последовательность чисел в указанном диапазоне.
Как перемешать (сделать случайным) массив в JavaScript?
Как объединить два массива в JavaScript и удалить дубликаты?
Как очистить массив в JavaScript?
Как удалить все дубликаты из массива объектов?
Выбор последнего элемента в массиве JavaScript