我正在寻找以下方法的任何替代方法,以创建包含1到N的JavaScript数组,其中N仅在运行时已知。
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
对我来说,我觉得应该有一种不用循环的方法。
我正在寻找以下方法的任何替代方法,以创建包含1到N的JavaScript数组,其中N仅在运行时已知。
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
对我来说,我觉得应该有一种不用循环的方法。
当前回答
尝试在Number的原型中添加迭代器。
Number.prototype[Symbol.iterator] = function *(){
let i = 0;
while(i < this) yield i++;
return;
}
现在数字是可迭代的,只需将一个数字传递给Array.from
Array.from(10);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
或者任何其他需要迭代的地方,比如。。。循环。
for(const number of 10) console.log(number);//logs 0 through 9 sequentially
这有点复杂,但也很酷。
其他回答
Fast
这个解决方案可能是最快的——它是由lodash_.range函数启发而来的(但我的更简单、更快)
设N=10,i=0,a=阵列(N);而(i<N)a[i++]=i;控制台日志(a);
与当前(2020.12.11)相比,基于while/for的现有答案的性能优势
内存在开始时由a=数组(N)分配一次使用了增加索引i++——看起来比减少索引i快30%左右——(可能是因为CPU缓存在正向上更快)
在此答案中,使用了20多种其他解决方案进行了速度测试
数组固有地管理其长度。当它们被遍历时,它们的索引可以保存在内存中并在此时被引用。如果需要知道随机索引,可以使用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()
Array(8).fill(0).map(Number.call, Number)
偷取Igors数字。可以使用技巧,但使用fill()稍微缩短。仅适用于ES6及以上版本。
我在寻找一个功能性的解决方案,最终得到了:
function numbers(min, max) {
return Array(max-min+2).join().split(',').map(function(e, i) { return min+i; });
}
console.log(numbers(1, 9));
注意:join().split(',')将稀疏数组转换为连续数组。
使用ES6的多种方式
使用扩展运算符(…)和键方法
[ ...Array(N).keys() ].map( i => i+1);
填充/贴图
Array(N).fill().map((_, i) => i+1);
排列自
Array.from(Array(N), (_, i) => i+1)
Array.from和{length:N}hack
Array.from({ length: N }, (_, i) => i+1)
关于广义形式的注记
通过将i+1更改为所需的表达式(例如i*2、-i、1+i*2和i%2等),上述所有形式都可以生成初始化为几乎任何所需值的数组。如果表达式可以用函数f表示,那么第一种形式就变得简单
[ ...Array(N).keys() ].map(f)
示例:
Array.from({length: 5}, (v, k) => k+1);
// [1,2,3,4,5]
由于数组在每个位置都是用undefined初始化的,因此v的值将是undefineed
展示所有表格的示例
让演示=(N)=>{控制台日志([…数组(N).keys()].map((i)=>i+1),数组(N).fill().map((_,i)=>i+1),数组.from(数组(N),(_,i)=>i+1),Array.from({length:N},(_,i)=>i+1))}演示(5)
具有自定义初始化函数f的更通用示例,即。
[ ...Array(N).keys() ].map((i) => f(i))
甚至更简单
[ ...Array(N).keys() ].map(f)
让demo=(N,f)=>{控制台日志([…数组(N).keys()].map(f),数组(N).fill().map((_,i)=>f(i)),数组.from(数组(N),(_,i)=>f(i)),数组.从({长度:N},(_,i)=>f(i)))}演示(5,i=>2*i+1)