JavaScript 有没有像“range()”这样的方法来在提供的范围内生成一个范围?

IT技术 javascript arrays functional-programming
2021-01-27 09:58:30

在 PHP 中,你可以做...

range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")

也就是说,有一个函数可以让你通过传递上界和下界来得到一个数字或字符的范围。

是否有任何内置于 JavaScript 的本机功能?如果没有,我将如何实施它?

6个回答

数字

[...Array(5).keys()];
 => [0, 1, 2, 3, 4]

字符迭代

String.fromCharCode(...[...Array('D'.charCodeAt(0) - 'A'.charCodeAt(0) + 1).keys()].map(i => i + 'A'.charCodeAt(0)));
 => "ABCD"

迭代

for (const x of Array(5).keys()) {
  console.log(x, String.fromCharCode('A'.charCodeAt(0) + x));
}
 => 0,"A" 1,"B" 2,"C" 3,"D" 4,"E"

作为函数

function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar, endChar) {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

作为类型函数

function range(size:number, startAt:number = 0):ReadonlyArray<number> {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar:string, endChar:string):ReadonlyArray<string> {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

lodash.js_.range()函数

_.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]
String.fromCharCode(..._.range('A'.charCodeAt(0), 'D'.charCodeAt(0) + 1));
 => "ABCD"

没有库的旧非 es6 浏览器:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
 => [0, 1, 2, 3, 4]

console.log([...Array(5).keys()]);

(ES6 归功于 nils petersohn 和其他评论者)

@Lewis 因为用它定义的数组有空槽,不会与map()它的朋友或它的一个朋友一起迭代
2021-03-10 09:58:30
因为如果它在任何地方都有用,那么它在 JS 中可能很有用。(JS 可以做函数式编程类型的东西,这可以从 range(0 语句。这和其他一千个原因它可能在一些半罕见的情况下有用)
2021-03-14 09:58:30
Array.from(Array(5).keys())
2021-03-19 09:58:30
知道为什么简单地使用(new Array(5)).map(function (value, index) { return index; })不起作用吗?这会[undefined × 5]在 Chrome DevTools 中返回给我。
2021-03-25 09:58:30
Array(5).fill() 也是可映射的
2021-03-28 09:58:30

对于数字,您可以使用 ES6 Array.from()现在除了 IE 之外它适用于所有事物

较短的版本:

Array.from({length: 20}, (x, i) => i);

更长的版本:

Array.from(new Array(20), (x, i) => i);​​​​​​

它创建了一个从 0 到 19 的数组。这可以进一步缩短为以下形式之一:

Array.from(Array(20).keys());
// or
[...Array(20).keys()];

也可以指定下限和上限,例如:

Array.from(new Array(20), (x, i) => i + *lowerBound*);

一篇更详细地描述这一点的文章:http : //www.2ality.com/2014/05/es6-array-methods.html

第一个例子甚至可以简化为 [...Array(20).keys()]
2021-03-11 09:58:30
@Delapouite 太棒了!你应该把它作为一个单独的答案,我会投票给它!这也是这个副本的完美答案
2021-03-15 09:58:30
Array.from()方法更简洁,比两者都快:Array(20).fill().map((_, i) => i)
2021-03-16 09:58:30
@Delapouite @jib 还有这个: Array.from({length: end - start}, (v, k) => k + start)
2021-03-25 09:58:30
@ icc97 是的,linters 可能会抱怨,尽管在 JavaScript 中省略了定义为与传递相同的函数参数undefined,因此fill()(没有参数)本身并没有该解决方案中不使用填充值,因此如果您愿意,可以使用它fill(0)来保存几个字符。
2021-04-04 09:58:30

我最喜欢的新表格(ES2015

Array(10).fill(1).map((x, y) => x + y)

如果你需要一个带step参数的函数

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)
@rodfersou 仅供参考:你的例子是错误的。stop实际上不是停止/结束位置而是计数/距离。(无意冒犯,只是为了让人们意识到错别字)
2021-03-11 09:58:30
对于困惑的人 - 由于在 F Lekschas 发表评论后 Rodfersou 的编辑,他的代码现在是正确的。
2021-03-16 09:58:30
let range = (start, stop, step=1) => Array(stop - start).fill(start).map((x, y) => x + y * step)
2021-03-20 09:58:30
您传入的参数Array(Math.ceil((stop - start) / step) + 1), 需要+1最后才能真正模仿 php 的“包容性”行为。
2021-03-31 09:58:30
这是实际回答完全实现range方法的 Javascript 函数的完整问题的最佳答案目前在此之上的所有其他(除了 lodash 的_.range)都实现了基本的迭代器,而不是具有 start、stop 和 step 的实际范围函数
2021-04-01 09:58:30

这是我的 2 美分:

function range(start, end) {
  return Array.apply(0, Array(end - 1))
    .map((element, index) => index + start);
}
这实际上是错误的,因为问题是要求开始和结束值。不是开始和计数/距离。
2021-04-06 09:58:30
这个答案没有按预期工作。输出不可用。
2021-04-06 09:58:30

它适用于字符和数字,通过可选步骤向前或向后。

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

js小提琴

如果您喜欢扩充本机类型,请将其分配给Array.range.