Есть ли в JavaScript метод типа range () для генерации диапазона в заданных пределах? - PullRequest
653 голосов
/ 09 октября 2010

В PHP вы можете сделать ...

range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")

То есть есть функция, которая позволяет получить диапазон чисел или символов, передав верхнюю и нижнюю границы.

Есть ли что-нибудь встроенное в JavaScript для этого? Если нет, то как бы я это реализовал?

Ответы [ 50 ]

1053 голосов
/ 07 апреля 2012

Числа

[...Array(5).keys()];
 => [0, 1, 2, 3, 4]

Итерация символов

String.fromCharCode(...[...Array('D'.charCodeAt(0) - 'A'.charCodeAt(0) + 1).keys()].map(i => i + 'A'.charCodeAt(0)));
 => "ABCD"

итерация

for (const x of Array(5).keys()) {
  console.log(x, String.fromCharCode('A'.charCodeAt(0) + x));
}
 => 0,"A" 1,"B" 2,"C" 3,"D" 4,"E"

Как функции

function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar, endChar) {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

как типизированные функции

function range(size:number, startAt:number = 0):ReadonlyArray<number> {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar:string, endChar:string):ReadonlyArray<string> {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

lodash.js _.range() функция

_.range(10);
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
 => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
 => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
String.fromCharCode(..._.range('A'.charCodeAt(0), 'D'.charCodeAt(0) + 1));
 => "ABCD"

Старые не es6 браузеры без библиотеки:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
 => [0, 1, 2, 3, 4]

console.log([...Array(5).keys()]);

Спасибо.

(кредит ES6 Нилсу Петерсону и другим комментаторам)

271 голосов
/ 10 апреля 2015

Для чисел вы можете использовать ES6 Array.from(), , который работает во все времена , за исключением IE:

Более короткая версия:

Array.from({length: 20}, (x,i) => i);

Более длинная версия:

Array.from(new Array(20), (x,i) => i)

, который создает массив от 0 до 19 включительно.Это может быть дополнительно сокращено до одной из следующих форм:

Array.from(Array(20).keys())
// or
[...Array(20).keys()]

Также можно указать нижнюю и верхнюю границы, например:

Array.from(new Array(20), (x,i) => i + *lowerBound*)

Статья, описывающая это более подробно: http://www.2ality.com/2014/05/es6-array-methods.html

99 голосов
/ 06 июля 2017

Моя новая любимая форма ( ES2015 )

Array(10).fill(1).map((x, y) => x + y)

А если вам нужна функция с параметром step:

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)
93 голосов
/ 22 октября 2013

Вот мои 2 цента:

function range(start, count) {
  return Array.apply(0, Array(count))
    .map((element, index) => index + start);
}
67 голосов
/ 09 октября 2010

Он работает для символов и чисел, двигаясь вперед или назад с необязательным шагом.

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

jsFiddle .

Если вам подходит расширение родных типовзатем присвойте его Array.range.

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

console.log(range("A", "Z", 1));
console.log(range("Z", "A", 1));
console.log(range("A", "Z", 3));


console.log(range(0, 25, 1));

console.log(range(0, 25, 5));
console.log(range(20, 5, 5));
41 голосов
/ 16 марта 2013

Простая функция диапазона:

function range(start, stop, step) {
    var a = [start], b = start;
    while (b < stop) {
        a.push(b += step || 1);
    }
    return a;
}
34 голосов
/ 27 июля 2017

ОК, в 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"]
34 голосов
/ 09 октября 2010
Array.range= function(a, b, step){
    var A= [];
    if(typeof a== 'number'){
        A[0]= a;
        step= step || 1;
        while(a+step<= b){
            A[A.length]= a+= step;
        }
    }
    else{
        var s= 'abcdefghijklmnopqrstuvwxyz';
        if(a=== a.toUpperCase()){
            b=b.toUpperCase();
            s= s.toUpperCase();
        }
        s= s.substring(s.indexOf(a), s.indexOf(b)+ 1);
        A= s.split('');        
    }
    return A;
}


    Array.range(0,10);
    // [0,1,2,3,4,5,6,7,8,9,10]

    Array.range(-100,100,20);
    // [-100,-80,-60,-40,-20,0,20,40,60,80,100]

    Array.range('A','F');
    // ['A','B','C','D','E','F')

    Array.range('m','r');
    // ['m','n','o','p','q','r']
23 голосов
/ 13 августа 2015

Удобная функция, чтобы сделать трюк, запустите фрагмент кода ниже

function range(start, end, step, offset) {
  
  var len = (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1;
  var direction = start < end ? 1 : -1;
  var startingPoint = start - (direction * (offset || 0));
  var stepSize = direction * (step || 1);
  
  return Array(len).fill(0).map(function(_, index) {
    return startingPoint + (stepSize * index);
  });
  
}

console.log('range(1, 5)=> ' + range(1, 5));
console.log('range(5, 1)=> ' + range(5, 1));
console.log('range(5, 5)=> ' + range(5, 5));
console.log('range(-5, 5)=> ' + range(-5, 5));
console.log('range(-10, 5, 5)=> ' + range(-10, 5, 5));
console.log('range(1, 5, 1, 2)=> ' + range(1, 5, 1, 2));

вот как это использовать

диапазон (начало, конец, шаг = 1, смещение = 0);

  • включительно - вперед range(5,10) // [5, 6, 7, 8, 9, 10]
  • включительно - назад range(10,5) // [10, 9, 8, 7, 6, 5]
  • шаг - назад range(10,2,2) // [10, 8, 6, 4, 2]
  • эксклюзив - вперед range(5,10,0,-1) // [6, 7, 8, 9] not 5,10 themselves
  • смещение - развернуть range(5,10,0,1) // [4, 5, 6, 7, 8, 9, 10, 11]
  • смещение - сжатие range(5,10,0,-2) // [7, 8]
  • шаг - развернуть range(10,0,2,2) // [12, 10, 8, 6, 4, 2, 0, -2]

надеюсь, вы найдете это полезным.


А вот как это работает.

Обычно я сначала вычисляю длину полученного массива и создаю массив, заполненный нулями до этой длины, затем заполняю его необходимыми значениями

  • (step || 1) => И другие, подобные этому, используют значение step и, если оно не было предоставлено, используют 1 вместо
  • Мы начнем с вычисления длины массива результатов, используя (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1), чтобы упростить его (разница * смещение в обоих направлениях / шагах)
  • После получения длины мы создаем пустой массив с инициализированными значениями, используя new Array(length).fill(0); отметьте здесь
  • Теперь у нас есть массив [0,0,0,..] необходимой длины. Мы отображаем его и возвращаем новый массив со значениями, которые нам нужны, используя Array.map(function() {})
  • var direction = start < end ? 1 : 0; Очевидно, что если start не меньше, чем end, нам нужно двигаться назад. Я имею в виду переход от 0 до 5 или наоборот
  • На каждой итерации startingPoint + stepSize * index даст нам необходимое нам значение
22 голосов
/ 27 марта 2016
var range = (l,r) => new Array(r - l).fill().map((_,k) => k + l);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...