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

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

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

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

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

Ответы [ 50 ]

16 голосов
/ 09 октября 2010

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

Если вы хотите перепроверить, определенным ресурсом является Стандарт ECMA-262 .

16 голосов
/ 30 декабря 2014

Использование Harmony Распределительный оператор и функции стрелок:

var range = (start, end) => [...Array(end - start + 1)].map((_, i) => start + i);

Пример:

range(10, 15);
[ 10, 11, 12, 13, 14, 15 ]
13 голосов
/ 25 января 2014

Провел некоторые исследования некоторых различных функций диапазона. Проверьте сравнение jsperf различных способов выполнения этих функций.Конечно, не полный или исчерпывающий список, но он должен помочь:)

Победитель ...

function range(lowEnd,highEnd){
    var arr = [],
    c = highEnd - lowEnd + 1;
    while ( c-- ) {
        arr[c] = highEnd--
    }
    return arr;
}
range(0,31);

Технически это не самый быстрый на Firefox, но сумасшедшийРазница в скорости (imho) на Chrome компенсирует это.

Также интересно наблюдать, насколько Chrome работает с этими функциями массива быстрее, чем Firefox. Chrome по крайней мере в 4 или 5 раз быстрее .

12 голосов
/ 11 июля 2015

Вы можете использовать lodash или Undescore.js range:

var range = require('lodash/range')
range(10)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

В качестве альтернативы, если вам нужен только последовательный диапазон целых чиселВы можете сделать что-то вроде:

Array.apply(undefined, { length: 10 }).map(Number.call, Number)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

В ES6 range может быть реализован с генераторами :

function* range(start=0, end=null, step=1) {
  if (end == null) {
    end = start;
    start = 0;
  }

  for (let i=start; i < end; i+=step) {
    yield i;
  }
}

Эта реализация экономит память при итерациибольшие последовательности, потому что не нужно материализовать все значения в массив:

for (let i of range(1, oneZillion)) {
  console.log(i);
}
10 голосов
/ 06 августа 2014

Интересной задачей было бы написать функцию кратчайший для этого.Рекурс на помощь!

function r(a,b){return a>b?[]:[a].concat(r(++a,b))}

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

Дополнительный бонус в том, что он запутывает.Потому что мы все знаем, как важно скрыть наш код от посторонних глаз.

Чтобы по-настоящему и полностью запутать функцию, сделайте следующее:

function r(a,b){return (a<b?[a,b].concat(r(++a,--b)):a>b?[]:[a]).sort(function(a,b){return a-b})}
8 голосов
/ 28 августа 2015

Я бы написал что-то вроде этого:

function range(start, end) {
    return Array(end-start).join(0).split(0).map(function(val, id) {return id+start});
}  

range(-4,2);
// [-4,-3,-2,-1,0,1]

range(3,9);
// [3,4,5,6,7,8]

Он ведет себя аналогично диапазону Python:

>>> range(-4,2)
[-4, -3, -2, -1, 0, 1]
8 голосов
/ 28 мая 2017

Другая версия с использованием генераторов ES6 (см. Отлично Паоло Моретти с генератором ES6 ):

const RANGE = (a,b) => Array.from((function*(x,y){
  while (x <= y) yield x++;
})(a,b));

console.log(RANGE(3,7));  // [ 3, 4, 5, 6, 7 ]

Или, если нам нужна только итерация, то:

const RANGE_ITER = (a,b) => (function*(x,y){
  while (x++< y) yield x;
})(a,b);

for (let n of RANGE_ITER(3,7)){
  console.log(n);
}
8 голосов
/ 15 февраля 2017

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

const getRange = (start, stop) => Array.from(
  new Array((stop - start) + 1),
  (_, i) => i + start
);
7 голосов
/ 09 июля 2014

Хотя это не из PHP , но имитация range из Python .

function range(start, end) {
    var total = [];

    if (!end) {
        end = start;
        start = 0;
    }

    for (var i = start; i < end; i += 1) {
        total.push(i);
    }

    return total;
}

console.log(range(10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
console.log(range(0, 10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(range(5, 10)); // [5, 6, 7, 8, 9] 
6 голосов
/ 28 января 2019

range(start,end,step): с помощью итераторов ES6

Вы запрашиваете только верхнюю и нижнюю границы. Здесь мы также создаем один с шагом.

Вы можете легко создать функцию генератора range(), которая может функционировать как итератор.Это означает, что вам не нужно предварительно генерировать весь массив.

function * range ( start, end, step = 1 ) {
  let state = start;
  while ( state < end ) {
    yield state;
    state += step;
  }
  return;
};

Теперь вы можете захотеть создать что-то, что предварительно генерирует массив из итератора и возвращает список.Это полезно для функций, которые принимают массив.Для этого мы можем использовать Array.from()

const generate_array = (start,end,step) =>
  Array.from( range(start,end,step) );

Теперь вы можете легко генерировать статический массив,

const array1 = generate_array(1,10,2);
const array1 = generate_array(1,7);

Но когда что-то требует итератор (или дает вам возможность использоватьитератор) вы тоже можете легко его создать.

for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
  console.log(i)
}

Специальные заметки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...