类似于 Python range() 的 JavaScript 函数

IT技术 javascript python
2021-03-06 18:31:26

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

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

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

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

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

bigOmega 的评论中,这可以使用Spread 语法来缩短

let range = n => [...Array(n).keys()]
@bigOmega Theconst将应用于函数本身,而不是它的返回值。您可能不想以任何方式修改该函数。
2021-04-21 18:31:26
@BharathRaja 很棒,谢谢!为什么不是常量?我会尽量使用 const :) 就像 Java 最终版本一样 ;)
2021-05-02 18:31:26
你说得对,我尽可能多地使用const,但在这里它只是对数组的引用,所以数组仍然是可编辑的:'D
2021-05-04 18:31:26
一个更简单的版本是 let range = n => [...Array(n).keys()]
2021-05-11 18:31:26
这个答案没有考虑起始索引和增加步长的能力。
2021-05-18 18:31:26

,没有,但你可以制作一个

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(),您可以使用上述解决方案。

也许进行一些额外的防御性检查 - 确保传递的参数都可以强制转换为数字并确保stop大于start(如果不是,则交换它们)。
2021-04-25 18:31:26
@delnan - 我不熟悉 Python 实现。我想如果它只会被熟悉 Python 实现的窥视者使用,那么模拟它是有意义的:)
2021-04-26 18:31:26
@RussCam:start >= stop如果目标是真正模拟 Python 的范围,则需要导致空数组。而且我认为无论如何它更直观。
2021-04-27 18:31:26
@RussCam:感谢您指出这一点。我没有为类型等添加防御性检查,但我实现了元素的相反顺序 - 当最后一个参数是负整数时,它现在的工作方式与 Python 对应物完全相同。
2021-05-01 18:31:26
@delnan:检查可能更复杂,因为简单start >= stop不足以使此函数range()在 Python 中表现得像我已经更新了我的答案。
2021-05-10 18:31:26

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


除了已经说过的内容之外,Javascript 1.7+ 还提供了对迭代器和生成器的支持,它们可用于创建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
@Tadeck:具有讽刺意味的是,我最近问了一个非常相似的问题,请查看 - 那里有一些很好的答案。顺便说一句,你的代码没有通过我的测试;(
2021-04-30 18:31:26
你能分享测试数据和预期结果吗?我很乐意改进它,但我的测试 100% 通过。你是说我给出的代码没有被你放在这个问题中的脚本正确解析:stackoverflow.com/q/12173856/548696
2021-05-01 18:31:26
+1 好主意!您能否也实现step参数并根据我的答案中的值对其进行测试您的回答非常适合我们考虑到非常具体的浏览器的应用程序(它不适用于 9 之前的 Google Chrome、Safari 和 IE 版本:stackoverflow.com/a/2209743/548696)。
2021-05-08 18:31:26
@Tadeck:没关系。我测试了切片,您的代码适用于范围。
2021-05-09 18:31:26
Python 的range“最后一个”值被排除在外(因此需要使用>=而不是>在上面的代码中)
2021-05-18 18:31:26

@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
@Gradiuss,将工作的step参数,但如果stop在,都没有通过start,并stop需要改变。我会更新它
2021-04-28 18:31:26
WTG,这是迄今为止最好的实现。它使用生成器(很好,因为不需要将整个序列存储在内存中)并且非常简洁。
2021-05-02 18:31:26
如果您使用 ES6,为什么不使用默认参数
2021-05-09 18:31:26
undefined 是一个指向像 null 这样的对象的指针。可以与 3 个等号进行比较,例如: if (stop === undefined) { 3 个等号是在不自动转换的情况下进行比较。compare as 也是比较类型。2 等号是与自动铸造到另一侧类型的比较。
2021-05-09 18:31:26

range来自 Python 2函数端口underscore.jslodash实用程序库(以及许多其他有用的工具)提供。从下划线文档中复制的示例:

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