JavaScript函数类似于Python范围()

有没有JavaScript的函数类似于Python的range()

我觉得应该有一个比每次写下面几行更好的方法:

 array = new Array(); for (i = 0; i < specified_len; i++) { array[i] = i; } 

,没有,但你可以做一个

JavaScript的Python range()的实现range()

试图模仿它在Python中的工作方式 ,我会创build类似于以下的函数:

 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的certificate。

在JavaScript和Python中range()之间的比较

它的工作原理如下:

  • range(4)返回[0, 1, 2, 3]
  • range(3,6)返回[3, 4, 5]
  • range(0,10,2)返回[0, 2, 4, 6, 8] range(0,10,2) [0, 2, 4, 6, 8]
  • range(10,0,-1)返回[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] range(10,0,-1) [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
  • range(8,2,-2)返回[8, 6, 4] range(8,2,-2) [8, 6, 4]
  • range(8,2)返回[]
  • range(8,2,2)返回[]
  • range(1,5,-1)返回[]
  • range(1,5,-2)返回[]

而且它的Python对应的工作方式也完全相同 (至less在上面提到的情况下):

 >>> 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()的函数,你可以使用上面提到的解决scheme。

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

 let range = n => Array.from(Array(n).keys()) 

除了已经说过的之外,Javascript 1.7+还提供了对迭代器和生成器的支持,它们可以用来创build懒惰的,内存有效的range版本,与Python2中的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的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); => [] 

干得好。

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

 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] 

把@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循环中使用它,您需要ES6 / JS1.7 for-of循环:

 for (let i of range(0, 10, 2)) { console.log(i); } // Outputs => 0 2 4 6 8 

可以通过将一个迭代器附加到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] 

采取从凯尔辛普森的课程反思asynchronousJavaScript

你可以使用下划线库。 它包含数十个有用的函数来处理数组等等。

用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 } 

为了得到一个大小为x的数组,这里是一个没有使用任何库的单线程

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

作为

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

如果您需要指定范围的起始位置和结束位置,则可以在这里find一个小的扩展名:

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

以下是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] 

仍然没有内build的function,相当于range() ,但与最新版本 – ES2015 – 你可以build立自己的实现。 这是一个有限的版本。 有限,因为它没有考虑到步骤参数。 只是最小,最大

const range = (min = null, max = null) => Array.from({length:max ? max - min : min}, (v,k) => max ? k + min : k)

这是通过Array.from方法能够从具有length属性的任何对象构build数组来完成的。 因此,传递一个简单的对象只有length属性将创build一个ArrayIterator,将产生length数量的对象。