我正在寻找以下方法的任何替代方法,以创建包含1到N的JavaScript数组,其中N仅在运行时已知。

var foo = [];

for (var i = 1; i <= N; i++) {
   foo.push(i);
}

对我来说,我觉得应该有一种不用循环的方法。


当前回答

ES6中还有另一种方法,使用Array.from,它接受两个参数,第一个是arrayLike(在本例中是具有长度属性的对象),第二个是映射函数(在本示例中,我们将项映射到其索引)

Array.from({length:10}, (v,i) => i)

它更短,可用于生成偶数等其他序列

Array.from({length:10}, (v,i) => i*2)

此外,这比大多数其他方式具有更好的性能,因为它只在阵列中循环一次。查看截图以进行一些比较

//打开开发控制台以查看结果计数=100000console.time(“来自对象”)for(设i=0;i<count;i++){range=Array.from({length:10},(v,i)=>i)}console.timeEnd(“来自对象”)console.time(“来自按键”)for(设i=0;i<count;i++){range=Array.from(Array(10).keys())}console.timeEnd(“来自按键”)console.time(“应用”)for(设i=0;i<count;i++){range=Array.apply(null,{length:10}).map(函数(元素,索引){return index;})}console.timeEnd(“应用”)

其他回答

我发现了这条旧线索,因为我自己也在想同样的问题,但我想这里没有一个答案比Kokodoko评论的原始示例更容易,哈哈!

我最终自己使用了这个方法:

var foo = [];
while (foo.length < N)
    foo.push( foo.length + 1 );

这至少比常规的for循环稍微快一点,而且希望不容易出错(尽管在计算上可能更昂贵)。

甚至可以做以下事情:

var foo= [];
while (foo.length < N)
    foo.push( foo.length%4 + 1 );

以按顺序将阵列填充1-4次。或者使用此方法用单个项填充数组,尽管我想在这种情况下,只使用array(N).fill(x)可能会更快。

数组固有地管理其长度。当它们被遍历时,它们的索引可以保存在内存中并在此时被引用。如果需要知道随机索引,可以使用indexOf方法。

也就是说,为了满足您的需要,您可能只需要声明一个特定大小的数组:

var foo = new Array(N);   // where N is a positive integer

/* this will create an array of size, N, primarily for memory allocation, 
   but does not create any defined values

   foo.length                                // size of Array
   foo[ Math.floor(foo.length/2) ] = 'value' // places value in the middle of the array
*/

ES6

传播

使用扩展运算符(…)和键方法,可以创建一个大小为N的临时数组来生成索引,然后创建一个可以分配给变量的新数组:

var foo = [ ...Array(N).keys() ];

填充/贴图

您可以首先创建所需数组的大小,用undefined填充它,然后使用map创建一个新数组,它将每个元素设置为索引。

var foo = Array(N).fill().map((v,i)=>i);

排列自

这应该是初始化到大小为N的长度,并一次填充数组。

Array.from({ length: N }, (v, i) => i)

代替注释和混淆,如果您真的想在上面的示例中获取1..N中的值,有几个选项:

如果索引可用,您可以简单地将其递增一(例如,++i)。在不使用索引的情况下——可能是一种更有效的方法——创建数组,但使N表示N+1,然后从前面移动。所以,如果你想要100个数字:let arr;(arr=[…数组(101).keys()]).shift()




function range(start, end) {
    var foo = [];
    for (var i = start; i <= end; i++) {
        foo.push(i);
    }
    return foo;
}

然后由调用

var foo = range(1, 5);

在Javascript中没有内置的方法来实现这一点,但如果您需要多次执行,则可以创建一个非常有效的实用程序函数。

编辑:在我看来,以下是一个更好的范围函数。也许只是因为我对LINQ有偏见,但我认为它在更多情况下更有用。您的里程数可能有所不同。

function range(start, count) {
    if(arguments.length == 1) {
        count = start;
        start = 0;
    }

    var foo = [];
    for (var i = 0; i < count; i++) {
        foo.push(start + i);
    }
    return foo;
}

基于高票答案和高票评论。

const range = (from, to) => [...Array(to + 1).keys()].slice(from);

// usage
let test = [];
test = range(5, 10);
console.log(test); // output: [ 5, 6, 7, 8, 9, 10 ]

对我来说,这是更有用的实用程序:

/**
 * create an array filled with integer numbers from base to length
 * @param {number} from
 * @param {number} to
 * @param {number} increment
 * @param {Array} exclude
 * @return {Array}
 */
export const count = (from = 0, to = 1, increment = 1, exclude = []) => {
  const array = [];
  for (let i = from; i <= to; i += increment) !exclude.includes(i) && array.push(i);
  return array;
};