JavaScript中是否有类似于Python的函数range()?
我认为应该有比每次编写以下几行更好的方法:
array = new Array();
for (i = 0; i < specified_len; i++) {
array[i] = i;
}
Answers:
不,没有,但您可以制造一个。
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(),则可以使用上述解决方案。
stop大于start(如果不是,则将其交换)。
start >= stop不足以使此函数像range()在Python中那样工作。我已经更新了答案。
对于ES6中非常简单的范围:
let range = n => Array.from(Array(n).keys())
根据bigOmega的评论,可以使用Spread语法将其缩短:
let range = n => [...Array(n).keys()]
let range = n => [...Array(n).keys()]
const尽可能多的方法,但是这里它只是对数组的引用,因此该数组仍可编辑:'D
const将应用于函数本身,而不是其返回值。您可能不想以任何方式修改该功能。
2018年:这个答案一直在投票,所以这里有一个更新。下面的代码已经过时,但是幸运的是ES6标准化的生成器和yield关键字,并且它们在各个平台上得到普遍支持。可以在这里找到延迟range()使用的示例。 yield
除了已经说过的内容外,Javascript 1.7+还提供了对迭代器和生成器的支持,这些迭代器和生成器可用于创建懒惰的,内存有效的range,类似于xrangePython2:
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
step参数并根据我的答案中的值对其进行测试吗?您的答案对于考虑到我们非常特定的浏览器的应用程序非常有用(它不适用于早于9的Google Chrome,Safari和IE版本:stackoverflow.com/a/2209743/548696)。
range“最后一个”值(因此需要使用而不是上面的代码)>=>
将来自@Tadeck和@georg的两个答案融合在一起,我想到了:
function* range(start, stop, step = 1) {
if (stop == null) {
// 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(5)) {
console.log(i);
}
// Outputs => 0 1 2 3 4
for (let i of range(0, 10, 2)) {
console.log(i);
}
// Outputs => 0 2 4 6 8
for (let i of range(10, 0, -2)) {
console.log(i);
}
// Outputs => 10 8 6 4 2
step参数,但如果stop在,都没有通过start,并stop需要改变。我将更新它
underscore.js和lodash实用程序库(以及许多其他有用的工具)range提供了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);
=> []
如果需要同时指定范围的开始位置和结束位置,以下是其中一个答案的小扩展名:
let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start);
为了获得大小数组x,这里是不使用任何库的单线
var range = n => Array(n + 1).join(1).split('').map((x, i) => i)
作为
> range(4)
[0, 1, 2, 3]
var range = n => Array(n).fill().map((e, i) => i);
x当您实际用作n参数名称时为何说'
以下是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对0or求值时返回或进入无限循环NaN,此生成器函数将引发类似于Python行为的异常。
使用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
}
pythonicrange使用JS的generators(yield)尽可能地模仿Python行为,同时支持range(stop)和range(start, stop, step)用例。此外,pythonic的range函式会传回一个Iterator与Python相似的物件,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的作者和维护者
MDN建议采用以下方法:序列生成器(范围)
// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
// Generate numbers range 0..4
console.log("range(0, 4, 1):", range(0, 4, 1));
// [0, 1, 2, 3, 4]
// Generate numbers range 1..10 with step of 2
console.log("\nrange(1, 10, 2):", range(1, 10, 2));
// [1, 3, 5, 7, 9]
// Generate the alphabet using Array.from making use of it being ordered as a sequence
console.log("\nrange('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x))", range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x)));
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
JavaScript中是否有类似于Python的range()的函数?
此处的所有解决方案均指的是Python 2的范围(可能是由于您提供的代码示例)。但是在Python 3中,range()方法返回一个迭代器。JavaScript还具有迭代器,并且迭代器比生成整个数组并将其存储在内存中更节省空间。
因此,Python 3range(n)函数的更准确表示是Array(n).keys()。
例如:
for (let i of Array(n).keys()) {
console.log(i) // 0, 1, 2, 3, ..., n
}
另一个例子(其他答案中已经介绍过)。将迭代器转换为数组(ES6):
let ary = [...Array(n).keys()];
// ary = [0, 1, 2, 3, ..., n]
仍然没有等效于的内置函数range(),但是使用最新版本-ES2015-您可以构建自己的实现。这是它的限定版。受限,因为它不考虑step参数。最小,最大。
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许多对象。
这是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}`)
}
-20来-30?
不,没有,但是您可以制造一个。
我偏爱范围的Python3行为。您将在以下JavaScript的Python range()的实现中找到:
function* range(start=0, end=undefined, step=1) {
if(arguments.length === 1) {end = start, start = 0}
[...arguments].forEach(arg => {
if( typeof arg !== 'number') {throw new TypeError("Invalid argument")}
})
if(arguments.length === 0) {throw new TypeError("More arguments neede")}
if(start >= end) return
yield start
yield* range(start + step, end, step)
}
// Use Cases
console.log([...range(5)])
console.log([...range(2, 5)])
console.log([...range(2, 5, 2)])
console.log([...range(2,3)])
// You can, of course, iterate through the range instance.
JavaScript中是否有类似于Python的range()的函数?
如之前的回答:不,没有。但是你可以自己做。我相信这对于ES6是一种有趣的方法。它的工作原理与Python 2.7非常相似range(),但它的动态性更高。
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
}
该函数可以三种不同的方式运行(就像Python的range()一样):
range(stop)range(start, stop)range(start, stop, step)这些例子:
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 ]
请注意in,您不必使用运算符(如python)遍历数组,而必须使用of。因此,i变量采用数组元素的值而不是索引。
for(let i of range(5))
{
// do something with i...
}
这是我的方法
let n = 5
[...Array(n).keys()].map(x=>{console.log(x)})
输出
0
1
2
3
4
range()Python工作方式的函数,因此您可以使用它。JavaScript中没有这样的功能,但是有一些用于不同框架的插件,例如RangeMooTools的类。