类似于Python range()的JavaScript函数

类似于Python range()的JavaScript函数,javascript,python,Javascript,Python,JavaScript中是否有类似于Python的range()的函数 我认为应该有更好的方法,而不是每次都写以下几行: array = new Array(); for (i = 0; i < specified_len; i++) { array[i] = i; } array=newarray(); 对于(i=0;i0&&start>=停止)| |(步骤0?i停止;i+=步骤){ 产量一; } } 要在for循环中使用它,需要ES6/JS1.7 for of循环: for(

JavaScript中是否有类似于Python的
range()
的函数

我认为应该有更好的方法,而不是每次都写以下几行:

array = new Array();
for (i = 0; i < specified_len; i++) {
    array[i] = i;
}
array=newarray();
对于(i=0;i
没有,没有,但是你可以做一个

JavaScript实现Python的
range()
尝试模拟它在Python中的工作方式,我将创建类似于以下内容的函数:

功能范围(启动、停止、步进){
if(typeof stop==“未定义”){
//定义了一个参数
停止=启动;
开始=0;
}
如果(步骤的类型==“未定义”){
步骤=1;
}
如果((步骤>0&&start>=停止)| |(步骤<0&&start 0?i停止;i+=步骤){
结果:推(i);
}
返回结果;
};
看看有没有证据

JavaScript和Python中
range()
的比较 其工作方式如下:

  • 范围(4)
    返回
    [0,1,2,3]
    ,
  • 范围(3,6)
    返回
    [3,4,5]
    ,
  • 范围(0,10,2)
    返回
    [0,2,4,6,8]
    ,
  • 范围(10,0,-1)
    返回
    [10,9,8,7,6,5,4,3,2,1]
    ,
  • 范围(8,2,-2)
    返回
    [8,6,4]
    ,
  • 范围(8,2)
    返回
    []
    ,
  • 范围(8,2,2)
    返回
    []
    ,
  • 范围(1,5,-1)
    返回
    []
    ,
  • 范围(1,5,-2)
    返回
    []
    ,
其Python对应项的工作方式与之完全相同(至少在上述情况下):

因此,如果您需要一个与Python的
range()类似的函数,您可以使用上述解决方案。

给您

这将使用索引编号写入(或覆盖)每个索引的值

Array.prototype.writeIndices = function( n ) {
    for( var i = 0; i < (n || this.length); ++i ) this[i] = i;
    return this;
};

2018年:这个答案不断获得支持,所以这里有一个更新。下面的代码已经过时,但幸运的是ES6标准化生成器和
yield
关键字,它们在跨平台上得到普遍支持。可以找到使用
yield
的惰性
range()
示例


除了前面提到的内容之外,Javascript 1.7+还提供了支持,可用于创建Python2中的
range
,simlar to
xrange
的惰性、内存效率高的版本:

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

您可以使用函数库。它包含数十个用于处理数组的有用函数以及更多函数。

Python 2中的
范围
函数的端口由和实用程序库(以及许多其他有用的工具)提供。从下划线文档复制的示例:

_.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);
=> []

将和的两个答案融合在一起,我得出以下结论:

功能*范围(启动、停止、步骤=1){
if(stop==null){
//定义了一个参数
停止=启动;
开始=0;
}
对于(让i=开始;步骤>0?i<停止:i>停止;i+=步骤){
产量一;
}
}
要在for循环中使用它,需要ES6/JS1.7 for of循环:

for(范围(5)的第i个){
控制台日志(i);
}
//输出=>01 2 3 4
对于(范围(0,10,2)的设i){
控制台日志(i);
}
//输出=>0 2 4 6 8
对于(设i的范围为(10,0,-2)){
控制台日志(i);
}
//输出=>10 8 6 4 2

使用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
}
let range=function*(开始=0,停止,步骤=1){
设cur=(stop==未定义)?0:开始;
设最大值=(停止==未定义)?开始:停止;
对于(设i=cur;步长<0?i>max:i
要获得大小为
x
的数组,这里有一个不使用任何库的单行程序

var range = n => Array(n + 1).join(1).split('').map((x, i) => i)
充当

> range(4)
[0, 1, 2, 3]

对于ES6中非常简单的范围:

let range = n => Array.from(Array(n).keys())
从开始,可以使用以下方法缩短此时间:


仍然没有与
range()
等效的内置函数,但使用最新版本ES2015,您可以构建自己的实现。这里是它的有限版本。有限是因为它没有考虑step参数。只需最小值,最大值

const range=(最小值=null,最大值=null)=>
from({length:max?max-min:min},(v,k)=>max?k+min:k)

这是通过
数组来实现的。from
方法能够从任何具有
length
属性的对象构建数组。因此,只使用
length
属性传入一个简单对象将创建一个数组迭代器,该迭代器将生成
length
数量的对象。

这里是answ的一个小扩展如果您需要指定范围的起始位置和结束位置,请执行以下操作:

let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start);

以下是Python函数对JavaScript的自然适应:

//生成从开始(包含)到停止(独占)的范围:
功能*范围(启动、停止、步骤=1){
如果(停止==未定义)[开始,停止]=[0,开始];
如果(步骤>0)而(开始<停止)产生开始,则开始+=步骤;
否则,如果(步骤<0)而(开始>停止)产生开始,则开始+=步骤;
否则抛出新的RangeError('range()步骤参数无效');
} 
//示例:
console.log([…范围(3)];//[0,1,2]
console.log([…范围(0,3)]);//[0,1,2]
console.log([…范围(0,3,-1)]);//[]
console.log([…范围(0,0)]);//[]
console.log([…范围(-3)]);//[]

log([…范围(-3,0)];//[-3,-2,-1]
可以通过在
编号
原型上附加迭代器来实现

  Number.prototype[Symbol.iterator] = function* () { 
     for (var i = 0; i <= this; i++) {
       yield i
     } 
  }

[...5] // will result in [0,1,2,3,4,5]
Number.prototype[Symbol.iterator]=函数*(){

对于(var i=0;i,这里是该范围的另一个
es6
实现

//范围::(从,到,步骤?)->[编号]
常数范围=(从,到,步长=1)=>{
//必要时交换值
[从,到]=从>到?[到,从]:[从,到]
//创建范围数组
返回[…数组(数学舍入((到-从)/步))
let range = n => [...Array(n).keys()]
let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start);
  Number.prototype[Symbol.iterator] = function* () { 
     for (var i = 0; i <= this; i++) {
       yield i
     } 
  }

[...5] // will result in [0,1,2,3,4,5]
import {range} from 'pythonic';
// ...
const results = range(5).map(wouldBeInvokedFiveTimes);
// `results` is now an array containing elements from
// 5 calls to wouldBeInvokedFiveTimes
npm install --save pythonic
let range = (start, end)=> {
    if(start === end) return [start];
    return [start, ...range(start + 1, end)];
}
let range = (start, end, step)=> {
    if(start === end) return [start];
    return [start, ...range(start + step, end)];
}
for (let i of Array(n).keys()) {
  console.log(i) // 0, 1, 2, 3, ..., n
}
let ary = [...Array(n).keys()];
// ary = [0, 1, 2, 3, ..., n]
function range(start, stop, step = 1) 
{
    // This will make the function behave as range(stop)
    if(arguments.length === 1)
    {
        return [...Array(arguments[0]).keys()]
    }

    // Adjusts step to go towards the stop value
    if((start > stop && !(step < 0)) ||
       (start < stop && !(step > 0)))
    {
        step *= -1
    }

    let returnArray = []
    // Checks if i is in the interval between start and stop no matter if stop
    // is lower than start or vice-versa
    for(let i = start; (i-start)*(i-stop) <= 0; i += step)
    {
        returnArray.push(i)
    }
    return returnArray
}
console.log(range(5))
console.log(range(-2, 2))
console.log(range(2, -2))
console.log(range(10, 20, 2))
[ 0, 1, 2, 3, 4 ]
[ -2, -1, 0, 1, 2 ]
[ 2, 1, 0, -1, -2 ]
[ 10, 12, 14, 16, 18, 20 ]
for(let i of range(5))
{
    // do something with i...
}
function range(start, end) {
  return Array.from(Array(end||start).keys()).slice(!!end*start)
}
let n = 5 
[...Array(n).keys()].map(x=>{console.log(x)})
0
1
2
3
4
function range(start, stop) {
    if (typeof stop == 'undefined') {
        stop = start;
        start = 0;
    }
   
    result = [...Array(stop).keys()].slice(start, stop);
    return result;
}
class range {

constructor(start, stop, step = 1) {
    //check for invalid input
    if (stop !== undefined && typeof stop !== 'number'
        || typeof start !== 'number'
        || typeof step !== 'number') {
        throw Error('invalid input for range function');
    }

    //check if second argument is provided
    if (stop === undefined) {
        stop = start;
        start = 0;
    }

    //initialize the object properties
    this.start = start;
    this.stop = stop;
    this.step = step;
}

//create the iterator object with Symbol.iterator
[Symbol.iterator]() {
    return {
        current: this.start,
        last: this.stop,
        step: this.step,
        //implement the next() method of the iterator
        next() {
            if (this.step === 0) {
                return { done: true };
            } else if (this.step > 0 ? this.current < this.last : this.current > this.last) {
                let value = this.current;
                this.current += this.step;
                return { done: false, value };
            } else {
                return { done: true };
            }
        }
    };
};
}
for (const num of new range(1, 10, 2)) {
console.log(num);
}
let arr = [...new range(10, -5, -1)];
let arr = Array.from(new range(10));