Функция JavaScript похожа на диапазон Python ()
39239 просмотра
16 ответа
Есть ли в JavaScript функция, похожая на функцию Python range()
?
Я думаю, что должен быть лучший способ, чем каждый раз писать следующие строки:
array = new Array();
for (i = 0; i < specified_len; i++) {
array[i] = i;
}
Автор: clwen
Источник
Размещён: 17.05.2019 02:32
Ответы (16)
69 плюса
Нет , нет, но вы можете сделать один .
JavaScript реализация Python range()
Пытаясь эмулировать, как это работает в Python , я бы создал функцию, подобную этой:
function range(start, stop, step) {
if (typeof stop == 'undefined') {
// one param defined
stop = start;
start = 0;
}
if (typeof step == 'undefined') {
step = 1;
}
if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
return [];
}
var result = [];
for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
result.push(i);
}
return result;
};
Смотрите это jsfiddle для доказательства.
Сравнение range()
в JavaScript и Python
Это работает следующим образом:
range(4)
возвращается[0, 1, 2, 3]
,range(3,6)
возвращается[3, 4, 5]
,range(0,10,2)
возвращается[0, 2, 4, 6, 8]
,range(10,0,-1)
возвращается[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
,range(8,2,-2)
возвращается[8, 6, 4]
,range(8,2)
возвращается[]
,range(8,2,2)
возвращается[]
,range(1,5,-1)
возвращается[]
,range(1,5,-2)
возвращается[]
,
и его аналог Python работает точно так же (по крайней мере, в упомянутых случаях):
>>> range(4)
[0, 1, 2, 3]
>>> range(3,6)
[3, 4, 5]
>>> range(0,10,2)
[0, 2, 4, 6, 8]
>>> range(10,0,-1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> range(8,2,-2)
[8, 6, 4]
>>> range(8,2)
[]
>>> range(8,2,2)
[]
>>> range(1,5,-1)
[]
>>> range(1,5,-2)
[]
Так что если вам нужна функция для работы аналогично Python range()
, вы можете использовать вышеупомянутое решение.
79 плюса
Для очень простого диапазона в ES6:
let range = n => Array.from(Array(n).keys())
Автор: user1969453
Размещён: 23.06.2016 12:59
25 плюса
2018: этот ответ продолжает получать голоса, так что вот обновление. Приведенный ниже код устарел, но, к счастью, ES6 стандартизировал генераторы и yield
ключевое слово, и они универсально поддерживаются на разных платформах. Пример ленивого range()
использования yield
можно найти здесь .
В дополнение к тому, что уже было сказано, Javascript 1.7+ обеспечивает поддержку итераторов и генераторов, которые можно использовать для создания ленивой, эффективной по памяти версии range
simlar to xrange
в Python2:
function range(low, high) {
return {
__iterator__: function() {
return {
next: function() {
if (low > high)
throw StopIteration;
return low++;
}
}
}
}
}
for (var i in range(3, 5))
console.log(i); // 3,4,5
Автор: georg
Размещён: 25.11.2011 11:10
16 плюса
Порт функции Python range
предоставляется библиотеками утилит underscore.js и lodash (наряду со многими другими полезными инструментами). Примеры, скопированные из документов с подчеркиванием:
_.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]
_.range(0);
=> []
Автор: Mark Amery
Размещён: 30.08.2014 04:09
15 плюса
Соединяя оба ответа от @Tadeck и @georg , я придумал следующее:
function* range(start, stop, step = 1) {
if (typeof stop === 'undefined') {
// one param defined
stop = start;
start = 0;
}
for (let i = start; step > 0 ? i < stop : i > stop; i += step) {
yield i;
}
}
Чтобы использовать его в цикле for, вам необходим цикл for-of ES6 / JS1.7:
for (let i of range(0, 10, 2)) {
console.log(i);
}
// Outputs => 0 2 4 6 8
Автор: janka102
Размещён: 24.10.2014 07:23
12 плюса
Может быть достигнуто путем присоединения итератора к Number
прототипу
Number.prototype[Symbol.iterator] = function* () {
for (var i = 0; i <= this; i++) {
yield i
}
}
[...5] // will result in [0,1,2,3,4,5]
Взято из курса Кайла Симпсона Переосмысление асинхронного JavaScript
Автор: mcha Размещён: 14.08.2017 12:377 плюса
Ну вот.
Это запишет (или перезапишет) значение каждого индекса с номером индекса.
Array.prototype.writeIndices = function( n ) {
for( var i = 0; i < (n || this.length); ++i ) this[i] = i;
return this;
};
Если вы не предоставите номер, он будет использовать текущую длину массива.
Используйте это так:
var array = [].writeIndices(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Автор: RightSaidFred
Размещён: 25.11.2011 06:48
5 плюса
Вот небольшое расширение для одного из ответов на тот случай, если вам нужно указать начальную и конечную позиции диапазона:
let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start);
Автор: Dmitrii Mikhailov
Размещён: 20.12.2016 05:09
4 плюса
Для получения массива размера x
, вот одна строка без использования какой-либо библиотеки
var range = n => Array(n + 1).join(1).split('').map((x, i) => i)
работает как
> range(4)
[0, 1, 2, 3]
Автор: bigOmega
Размещён: 23.03.2016 03:52
4 плюса
Ниже приведена естественная адаптация функции Python range () к JavaScript:
// Generate range from start (inclusive) to stop (exclusive):
function* range(start, stop, step = 1) {
if (stop === undefined) [start, stop] = [0, start];
if (step > 0) while (start < stop) yield start, start += step;
else if (step < 0) while (start > stop) yield start, start += step;
else throw new RangeError('range() step argument invalid');
}
// Examples:
console.log([...range(3)]); // [0, 1, 2]
console.log([...range(0, 3)]); // [0, 1, 2]
console.log([...range(0, 3, -1)]);// []
console.log([...range(0, 0)]); // []
console.log([...range(-3)]); // []
console.log([...range(-3, 0)]); // [-3, -2, -1]
Он поддерживает любой аргумент , который можно сравнить с 0
и stop
и может быть увеличен путем step
. Он ведет себя идентично версии Python при использовании с числами, не превышающими Number.MAX_SAFE_INTEGER
.
Обратите внимание на следующие угловые случаи:
[...range(0, 0, 0)]; // RangeError: range() step argument invalid
[...range(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 2)]; // []
[...range(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 3)]; // Infinite loop
[...range(0.7, 0.8, 0.1)]; // [0.7, 0.7999999999999999]
[...range('1', '11')]; // ['1']
[...range('2', '22')]; // Infinite loop
В отличие от @ Tadeck - х , @ Volv - х и @ janka102 в ответ , который вернется []
, undefined
или войти в бесконечный цикл , когда имеет step
значение 0
или NaN
, эта функция генератор генерирует исключение , похожее на поведение Python.
3 плюса
Далее уточняется с параметрами по умолчанию ES6.
let range = function*(start = 0, stop, step = 1) {
let cur = (stop === undefined) ? 0 : start;
let max = (stop === undefined) ? start : stop;
for (let i = cur; step < 0 ? i > max : i < max; i += step)
yield i
}
Автор: Volv
Размещён: 22.02.2016 09:47
2 плюса
Вы можете использовать библиотеку подчеркивания . Он содержит десятки полезных функций для работы с массивами и многое другое.
Автор: Radagast Размещён: 24.08.2014 10:580 плюса
Все еще нет встроенной функции, которая эквивалентна range()
, но с самой последней версией - ES2015 - вы можете создать свою собственную реализацию. Вот ограниченная версия этого. Ограничено, поскольку не учитывает параметр шага. Просто мин, макс.
const range = (min = null, max = null) => Array.from({length:max ? max - min : min}, (v,k) => max ? k + min : k)
Это достигается с помощью Array.from
метода, способного построить массив из любого объекта, который имеет length
свойство. Таким образом, передача простого объекта с length
одним свойством создаст ArrayIterator, который выдаст length
количество объектов.
0 плюса
Вот еще одна es6
реализация ассортимента
// range :: (from, to, step?) -> [Number]
const range = (from, to, step = 1) => {
//swap values if necesery
[from, to] = from > to ? [to, from] : [from, to]
//create range array
return [...Array(Math.round((to - from) / step))]
.map((_, index) => {
const negative = from < 0 ? Math.abs(from) : 0
return index < negative ?
from + index * step :
(index - negative + 1) * step
})
}
range(-20, 0, 5)
.forEach(val => console.log(val))
for(const val of range(5, 1)){
console.log(`value ${val}`)
}
0 плюса
pythonic
range
лучше всего имитирует поведение Python, используя JS 'Generators ( yield
), поддерживая как варианты , так range(stop)
и range(start, stop, step)
варианты использования. Кроме того, функция pythonic
's range
возвращает пользовательский Generator
объект, который поддерживает map
и filter
, таким образом, можно сделать такие однообразные строки, как:
import {range} from 'pythonic';
// ...
const results = range(5).map(wouldBeInvokedFiveTimes);
// `results` is now an array containing elements from
// 5 calls to wouldBeInvokedFiveTimes
Установите с помощью npm
:
npm install --save pythonic
Вот код pythonic
для диапазона:
function range(...args) {
if (args.length < 2) {
return new Generator(rangeGeneratorWithStop(...args));
}
return new Generator(rangeGeneratorWithSartAndStopAndStep(...args));
}
const rangeGeneratorWithStop = stop => function * () {
for (let i = 0; i < stop; i++) {
yield i;
}
};
const rangeGeneratorWithSartAndStopAndStep = (start, stop, step = 1) => function * () {
for (let i = start; i < stop; i += step) {
yield i;
}
};
function range(...args) {
if (args.length < 2) {
return new Generator(rangeGeneratorWithStop(...args));
}
return new Generator(rangeGeneratorWithSartAndStopAndStep(...args));
}
class Generator {
constructor(generatorFn) {
this[Symbol.iterator] = generatorFn;
}
map(callbackFn) {
const result = [];
for (const element of this) {
result.push(callbackFn(element));
}
return result;
}
filter(callbackFn) {
const result = [];
for (const element of this) {
if (callbackFn(element)) {
result.push(element);
}
}
return result;
}
toArray() {
return Array.from(this);
}
}
Автор: Keyvan
Размещён: 04.04.2018 04:12
0 плюса
MDN рекомендует такой подход: генератор последовательностей (диапазон)
Автор: IliasT Размещён: 22.04.2019 08:44Вопросы из категории :
- javascript Как определить, какой из указанных шрифтов был использован на веб-странице?
- javascript Валидация клиентской стороны ASP.Net
- javascript Длина объекта JavaScript
- javascript Получение текста из выпадающего списка
- javascript Скрипт входа со скрытыми кнопками
- javascript Как автоматически изменить размер текстовой области с помощью Prototype?
- javascript Удаление элементов с помощью Array.map в JavaScript
- javascript Прокрутка переполненных DIV с помощью JavaScript
- javascript API Карт Google - проблемы с классом GLatLngBounds
- javascript Проверка десятичных чисел в JavaScript - IsNumeric ()
- python Обработка XML в Python
- python Как я могу использовать Python itertools.groupby ()?
- python Python: На какой ОС я работаю?
- python Как я могу создать непосредственно исполняемое кроссплатформенное приложение с графическим интерфейсом на Python?
- python Вызов функции модуля с использованием его имени (строки)
- python Звук Питона («Колокол»)
- python Regex и unicode
- python Создать зашифрованный ZIP-файл в Python
- python Создайте базовый итератор Python
- python Функция транспонирования / распаковки (обратная сторона zip)?