我正在寻找以下方法的任何替代方法,以创建包含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);
}
对我来说,我觉得应该有一种不用循环的方法。
当前回答
https://stackoverflow.com/a/49577331/8784402
使用Delta
对于javascript
smallest and one-liner[...Array(N)].map((v, i) => from + i * step);
示例和其他备选方案
Array.from(Array(10).keys()).map(i => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
[...Array(10).keys()].map(i => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Array(10).fill(0).map((v, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Array(10).fill().map((v, i) => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
[...Array(10)].map((v, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Range Function
const range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
range(0, 9, 2);
//=> [0, 2, 4, 6, 8]
// can also assign range function as static method in Array class (but not recommended )
Array.range = (from, to, step) =>
[...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);
Array.range(2, 10, 2);
//=> [2, 4, 6, 8, 10]
Array.range(0, 10, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Array.range(2, 10, -1);
//=> []
Array.range(3, 0, -1);
//=> [3, 2, 1, 0]
As Iterators
class Range {
constructor(total = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
for (let i = 0; i < total; yield from + i++ * step) {}
};
}
}
[...new Range(5)]; // Five Elements
//=> [0, 1, 2, 3, 4]
[...new Range(5, 2)]; // Five Elements With Step 2
//=> [0, 2, 4, 6, 8]
[...new Range(5, -2, 10)]; // Five Elements With Step -2 From 10
//=>[10, 8, 6, 4, 2]
[...new Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]
// Also works with for..of loop
for (i of new Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
As Generators Only
const Range = function* (total = 0, step = 1, from = 0) {
for (let i = 0; i < total; yield from + i++ * step) {}
};
Array.from(Range(5, -2, -10));
//=> [-10, -12, -14, -16, -18]
[...Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]
// Also works with for..of loop
for (i of Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
// Lazy loaded way
const number0toInf = Range(Infinity);
number0toInf.next().value;
//=> 0
number0toInf.next().value;
//=> 1
// ...
带步长/增量的从到
using iteratorsclass Range2 {
constructor(to = 0, step = 1, from = 0) {
this[Symbol.iterator] = function* () {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
}
}
[...new Range2(5)]; // First 5 Whole Numbers
//=> [0, 1, 2, 3, 4, 5]
[...new Range2(5, 2)]; // From 0 to 5 with step 2
//=> [0, 2, 4]
[...new Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
using Generators
const Range2 = function* (to = 0, step = 1, from = 0) {
let i = 0,
length = Math.floor((to - from) / step) + 1;
while (i < length) yield from + i++ * step;
};
[...Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
let even4to10 = Range2(10, 2, 4);
even4to10.next().value;
//=> 4
even4to10.next().value;
//=> 6
even4to10.next().value;
//=> 8
even4to10.next().value;
//=> 10
even4to10.next().value;
//=> undefined
对于字体
class _Array<T> extends Array<T> {
static range(from: number, to: number, step: number): number[] {
return Array.from(Array(Math.floor((to - from) / step) + 1)).map(
(v, k) => from + k * step
);
}
}
_Array.range(0, 9, 1);
其他回答
ES5版本,效率很低,但可能是最短的一个,它是一个表达式,而不是一个变量填充有例如for循环的语句:
(Array(N)+'').split(',').map(function(d,i){return i})
让我们分享我的:p
Math.pow(2, 10).toString(2).split('').slice(1).map((_,j) => ++j)
最终总结报告。。Drrruummm Rolll公司-
这是在不使用ES6的情况下生成大小为N(此处为10)的数组的最短代码。Cocco上面的版本很接近,但不是最短的。
(function(n){for(a=[];n--;a[n]=n+1);return a})(10)
但这场“代码高尔夫”(用最少的源代码字节来解决特定问题的比赛)无可争议的赢家是Niko Ruotsalainen。使用数组构造函数和ES6扩展运算符。(大多数ES6语法都是有效的typeScript,但下面不是。所以在使用它时要谨慎)
[...Array(10).keys()]
比字符串变体简单一点:
// create range by N
Array(N).join(0).split(0);
// create a range starting with 0 as the value
Array(7).join(0).split(0).map((v, i) => i + 1) // [1, 2, 3, 4, 5, 6, 7]
更新(2018年1月4日):更新以解决确切的OP问题。感谢@lessless发出此消息!
数组固有地管理其长度。当它们被遍历时,它们的索引可以保存在内存中并在此时被引用。如果需要知道随机索引,可以使用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()