我正在寻找下面的任何替代方法来创建一个包含1到N的JavaScript数组,其中N只在运行时才知道。
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
对我来说,感觉应该有一种没有循环的方法。
答案 0 :(得分:795)
你可以这样做:
var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)
结果:[0,1,2,3,4,5,6,7,8,9]
或随机值:
Array.apply(null, {length: N}).map(Function.call, Math.random)
结果:[0.7082694901619107,0.9572225909214467,0.8586748542729765, 0.8653848143294454,078339877473190427,0.9911756622605026,0.8133423360995948,0.8377588465809822,0.5577575915958732,0.16363654541783035]
首先,请注意Number.call(undefined, N)
相当于Number(N)
,只返回N
。我们稍后会使用这个事实。
Array.apply(null, [undefined, undefined, undefined])
相当于Array(undefined, undefined, undefined)
,它生成一个三元素数组并为每个元素分配undefined
。
如何将其概括为 N 元素?考虑Array()
的工作原理,如下所示:
function Array() {
if ( arguments.length == 1 &&
'number' === typeof arguments[0] &&
arguments[0] >= 0 && arguments &&
arguments[0] < 1 << 32 ) {
return [ … ]; // array of length arguments[0], generated by native code
}
var a = [];
for (var i = 0; i < arguments.length; i++) {
a.push(arguments[i]);
}
return a;
}
Since ECMAScript 5,Function.prototype.apply(thisArg, argsArray)
也接受鸭子类型的数组对象作为其第二个参数。如果我们调用Array.apply(null, { length: N })
,那么它将执行
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.push(/* arguments[i] = */ undefined);
}
return a;
}
现在我们有一个 N 元素数组,每个元素都设置为undefined
。当我们在其上调用.map(callback, thisArg)
时,每个元素都将设置为callback.call(thisArg, element, index, array)
的结果。因此,[undefined, undefined, …, undefined].map(Number.call, Number)
会将每个元素映射到(Number.call).call(Number, undefined, index, array)
,这与Number.call(undefined, index, array)
相同,正如我们之前观察到的那样,它会评估为index
。这样就完成了元素与索引相同的数组。
为什么要经历Array.apply(null, {length: N})
而不仅仅是Array(N)
的麻烦?毕竟,这两个表达式都会产生一个 N 元素的未定义元素数组。不同之处在于,在前一个表达式中,每个元素都显式 set 为undefined,而在后者中,每个元素都从未设置过。根据{{3}}的文件:
仅对已分配值的数组的索引调用
callback
;对于已删除或从未分配过值的索引,不会调用它。
因此,Array(N)
不足; Array(N).map(Number.call, Number)
会导致未初始化的数组 N 。
由于此技术依赖于ECMAScript 5中指定的Function.prototype.apply()
行为,因此在ECMAS和Chrome浏览器9之前的ECMAScript 5浏览器中它将.map()
。
答案 1 :(得分:766)
Array.from(Array(10).keys())
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
使用spread operator缩短版本。
[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
答案 2 :(得分:303)
Array.from({length: 5}, (v, k) => k+1);
// [1,2,3,4,5]
因此:
Array.from({length: N}, (v, k) => k+1);
// [1,2,3,...,N]
由于每个位置都使用undefined
初始化数组,因此v
的值将为undefined
const range = (N) => Array.from({length: N}, (v, k) => k+1) ;
console.log(
range(5)
)
答案 3 :(得分:266)
如果我得到你想要的东西,你需要一组数字1..n
,你可以在以后循环。
如果这就是您所需要的,那么您可以这样做吗?
var foo = new Array(45); // create an empty array with length 45
然后当你想要使用它时...(未经优化,仅举例)
for(var i = 0; i < foo.length; i++){
document.write('Item: ' + (i + 1) + ' of ' + foo.length + '<br/>');
}
e.g。如果您不需要存储数组中的任何内容,您只需要一个可以迭代的正确长度的容器......这可能会更容易。
在此处查看此行动:http://jsfiddle.net/3kcvm/
答案 4 :(得分:138)
我知道你的问题是要求用数字填充数组,但我不确定你为什么要这样做。
阵列固有地管理他们的长度。当它们被遍历时,它们的索引可以保存在内存中并在那时被引用。如果需要知道随机索引,则可以使用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
*/
利用扩展运算符(...
)和keys
方法,可以创建大小为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)
答案 5 :(得分:102)
使用非常受欢迎的 Underscore _.range method
// _.range([start], stop, [step])
_.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); // => []
答案 6 :(得分:63)
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;
}
答案 7 :(得分:52)
在v8中填充Array
的最快方法是:
[...Array(5)].map((_,i) => i);
结果将为:[0, 1, 2, 3, 4]
答案 8 :(得分:43)
您可以使用:
new Array(/*any number which you want*/)
.join().split(',')
.map(function(item, index){ return ++index;})
例如
new Array(10)
.join().split(',')
.map(function(item, index){ return ++index;})
将创建以下数组:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
答案 9 :(得分:38)
ES6这将解决问题:
[...Array(12).keys()]
查看结果:
[...Array(12).keys()].map(number => console.log(number))
&#13;
答案 10 :(得分:38)
如果您正好在我的应用中使用d3.js,那么D3会为您提供辅助功能。
所以要从0到4获得一个数组,它就像:
一样简单d3.range(5)
[0, 1, 2, 3, 4]
并从1到5获取数组,正如您所要求的那样:
d3.range(1, 5+1)
[1, 2, 3, 4, 5]
查看this tutorial了解详情。
答案 11 :(得分:37)
这可能是生成数组的最快方法
最短
var a=[],b=N;while(b--)a[b]=b+1;
内联
var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]);
//arr=[0,1,2,3,4,5,6,7,8,9]
如果你想从1开始
var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]);
//arr=[1,2,3,4,5,6,7,8,9,10]
想要一个功能吗?
function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder
var arr=range(10,5);
//arr=[5,6,7,8,9,10,11,12,13,14]
<强> WHY吗
while
是最快的循环
直接设置比push
[]
比new Array(10)
很简单......看看第一个代码。然后看看这里的所有其他功能。
如果你愿意,没有
就无法生存for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]
或
for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]
答案 12 :(得分:33)
使用ES2015 / ES6传播运营商
[...Array(10)].map((_, i) => i + 1)
console.log([...Array(10)].map((_, i) => i + 1))
&#13;
答案 13 :(得分:29)
填充Array
的新方法是:
const array = [...Array(5).keys()]
console.log(array)
结果将为:[0, 1, 2, 3, 4]
答案 14 :(得分:29)
这个问题有很多复杂的答案,但是很简单:
[...Array(255).keys()].map(x => x + 1)
此外,尽管以上内容简短(简洁),但我认为以下内容会更快 (最大长度为:
127,Int8
255,Uint8和
32,767,Int16,
65,535,Uint16,
2,147,483,647,Int32,
4,294,967,295,Uint32。
(基于max integer values),另请参见Typed Arrays):
(new Uint8Array(255)).map(($,i) => i + 1);
尽管该解决方案也不是那么理想,因为它创建了两个数组,并使用了额外的变量声明“ $”(不确定使用此方法解决该问题的任何方法)。我认为以下解决方案是绝对可行的最快方法:
for(var i = 0, arr = new Uint8Array(255); i < arr.length; i++) arr[i] = i + 1;
在执行此语句后,您随时可以在当前作用域中简单地使用变量“ arr”;
如果您想使用它做一个简单的功能(需要进行一些基本验证):
function range(min, max) {
min = min && min.constructor == Number ? min : 0;
!(max && max.constructor == Number && max > min) && // boolean statements can also be used with void return types, like a one-line if statement.
((max = min) & (min = 0)); //if there is a "max" argument specified, then first check if its a number and if its graeter than min: if so, stay the same; if not, then consider it as if there is no "max" in the first place, and "max" becomes "min" (and min becomes 0 by default)
for(var i = 0, arr = new (
max < 128 ? Int8Array :
max < 256 ? Uint8Array :
max < 32768 ? Int16Array :
max < 65536 ? Uint16Array :
max < 2147483648 ? Int32Array :
max < 4294967296 ? Uint32Array :
Array
)(max - min); i < arr.length; i++) arr[i] = i + min;
return arr;
}
//and you can loop through it easily using array methods if you want
range(1,11).forEach(x => console.log(x));
//or if you're used to pythons `for...in` you can do a similar thing with `for...of` if you want the individual values:
for(i of range(2020,2025)) console.log(i);
//or if you really want to use `for..in`, you can, but then you will only be accessing the keys:
for(k in range(25,30)) console.log(k);
console.log(
range(1,128).constructor.name,
range(200).constructor.name,
range(400,900).constructor.name,
range(33333).constructor.name,
range(823, 100000).constructor.name,
range(10,4) // when the "min" argument is greater than the "max", then it just considers it as if there is no "max", and the new max becomes "min", and "min" becomes 0, as if "max" was never even written
);
答案 15 :(得分:29)
如果您使用的是lodash,则可以使用_.range:
_.range([start=0], end, [step=1])
创建一个数字数组 (正面和/或负面)从开始到进展,但不是 包括,结束。如果指定了负启动,则使用-1的步长 没有结束或步骤。如果未指定end,则将其设置为start 然后设置为0。
示例:
_.range(4);
// ➜ [0, 1, 2, 3]
_.range(-4);
// ➜ [0, -1, -2, -3]
_.range(1, 5);
// ➜ [1, 2, 3, 4]
_.range(0, 20, 5);
// ➜ [0, 5, 10, 15]
_.range(0, -4, -1);
// ➜ [0, -1, -2, -3]
_.range(1, 4, 0);
// ➜ [1, 1, 1]
_.range(0);
// ➜ []
答案 16 :(得分:25)
最终摘要报告.. Drrruummm Rolll -
这是 最短代码 ,用于生成大小为N的数组(此处为10),而不使用ES6 。 Cocco上面的版本很接近但不是最短的。
(function(n){for(a=[];n--;a[n]=n+1);return a})(10)
但本代码高尔夫的无可争议的胜利者(用于解决源代码中最少字节的特定问题的竞争)是Niko Ruotsalainen。使用Array Constructor和 ES6 spread operator 。 (大多数ES6语法都是有效的typeScript,但是后面的不是。所以在使用它时要明智)
[...Array(10).keys()]
答案 17 :(得分:24)
使用ES6,您可以执行以下操作:
// `n` is the size you want to initialize your array
// `null` is what the array will be filled with (can be any other value)
Array(n).fill(null)
答案 18 :(得分:22)
非常简单和容易地生成恰好 1 - N
const [, ...result] = Array(11).keys();
console.log('Result:', result);
答案 19 :(得分:17)
Array.from({length: 1000}, (_, i) => i).slice(1);
或更好(没有额外的变量_,也没有额外的slice
调用):
Array.from({length:1000}, Number.call, i => i + 1)
或者为获得更快的结果,如果列表少于256个结果,则可以使用Uint8Array(或者可以根据列表的短短使用其他Uint列表,例如Uint16的最大数目为65535,或者Uint32最多为4294967295等。Officially, these typed arrays were only added in ES6 though)。例如:
Uint8Array.from({length:10}, Number.call, i => i + 1)
Array.apply(0, {length: 1000}).map(function(){return arguments[1]+1});
或者,在ES5中,对于map函数(如上述ES6中Array.from
函数的第二个参数),可以使用Number.call
Array.apply(0,{length:1000}).map(Number.call,Number).slice(1)
或者,如果您在此处也反对.slice
,则可以执行与上述等效的ES5(来自ES6),例如:
Array.apply(0,{length:1000}).map(Number.call, Function("i","return i+1"))
答案 20 :(得分:17)
在ES6中还有另一种方法,使用Array.from取两个参数,第一个是arrayLike(在本例中是一个具有length
属性的对象),第二个是映射函数(在在这种情况下,我们将项目映射到其索引)
Array.from({length:10}, (v,i) => i)
这个更短,可用于其他序列,如生成偶数
Array.from({length:10}, (v,i) => i*2)
此外,它具有比大多数其他方式更好的性能,因为它只在数组中循环一次。 检查snippit进行一些比较
// open the dev console to see results
count = 100000
console.time("from object")
for (let i = 0; i<count; i++) {
range = Array.from({length:10}, (v,i) => i )
}
console.timeEnd("from object")
console.time("from keys")
for (let i =0; i<count; i++) {
range = Array.from(Array(10).keys())
}
console.timeEnd("from keys")
console.time("apply")
for (let i = 0; i<count; i++) {
range = Array.apply(null, { length: 10 }).map(function(element, index) { return index; })
}
console.timeEnd("apply")
答案 21 :(得分:13)
for(var i,a=[i=0];i<10;a[i++]=i);
a = [1,2,3,4,5,6,7,8,9,10]
答案 22 :(得分:13)
使用ES6标准中的新数组方法和=>
函数语法(在编写本文时仅使用Firefox)。
用undefined
填充漏洞:
Array(N).fill().map((_, i) => i + 1);
Array.from
将“漏洞”变为undefined
,以便Array.map
按预期工作:
Array.from(Array(5)).map((_, i) => i + 1)
答案 23 :(得分:11)
https://stackoverflow.com/a/49577331/8784402
const products = [
{
id: 1,
name: 'lorem'
},
{
id: 3,
name: 'ipsum'
}
];
const tmp_products = [
{
id: 1,
name: 'lorem'
},
{
id: 14,
name: 'porros'
},
{
id: 3,
name: 'ipsum'
},
{
id: 105,
name: 'dolor'
},
{
id: 32,
name: 'simet'
}
];
const missingIndex = tmp_products.reduce((acc, curV, curI) => {
if (!products.some((item) => item.id === curV.id && item.name === curV.name)) {
acc.push(curI);
}
return acc;
}, []);
console.log(missingIndex);
示例和其他替代方法
[...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]
作为迭代器
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]
仅作为发电机
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
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
// ...
使用发电机
class 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]
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
答案 24 :(得分:9)
比字符串变体简单一点:
// 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]
更新(1/4/2018):已更新,以解决确切的OP问题。谢谢@lessless打电话给我!
答案 25 :(得分:9)
这个相当完整的答案清单中目前唯一的味道似乎是一个以发电机为特色的;所以补救一下:
const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]
可以这样使用:
gen(4) // [0,1,2,3]
关于这一点的好处是你不必增加......为了从@ igor-shubin给出的答案中获得灵感,你可以很容易地创建一系列的randoms:
const gen = N => [...(function*(){let i=0;
while(i++<N) yield Math.random()
})()]
而不是冗长在某种程度上非常昂贵,如:
const slow = N => new Array(N).join().split(',').map((e,i)=>i*5)
// [0,5,10,15,...]
你可以改为:
const fast = N => [...(function*(){let i=0;while(i++<N)yield i*5})()]
答案 26 :(得分:9)
你可以这样做:
var arr = Array.from(Array(10).keys())
arr.shift()
console.log(arr)
答案 27 :(得分:8)
Iterable版本使用的generator函数不会修改Number.prototype
。
function sequence(max, step = 1) {
return {
[Symbol.iterator]: function* () {
for (let i = 1; i <= max; i += step) yield i
}
}
}
console.log([...sequence(10)])
&#13;
答案 28 :(得分:8)
试试这个:
var foo = [1, 2, 3, 4, 5];
如果您使用的是CoffeeScript,则可以通过执行以下操作来创建范围:
var foo = [1..5];
否则,如果您使用的是vanilla JavaScript,如果要将数组初始化为可变长度,则必须使用循环。
答案 29 :(得分:7)
Just another ES6 version.
By making use of Array.from
second optional argument:
Array.from(arrayLike[, mapFn[, thisArg]])
We can build the numbered array from the empty Array(10)
positions:
Array.from(Array(10), (_, i) => i)
var arr = Array.from(Array(10), (_, i) => i);
document.write(arr);
答案 30 :(得分:7)
Array(8).fill(0).map(Number.call, Number)
窃取Igors Number.call
技巧,但使用fill()
稍微缩短。仅适用于ES6及以上版本。
答案 31 :(得分:7)
map()
答案 32 :(得分:7)
Object.keys(Array.apply(0, Array(3))).map(Number)
强> 返回[0, 1, 2]
。与Igor Shubin's excellent answer非常相似,但诡计略少(并且一个字符更长)。
Array(3) // [undefined × 3]
生成长度为n = 3的数组。不幸的是,这个阵列对我们来说几乎没用,所以我们必须...... Array.apply(0,Array(3)) // [undefined, undefined, undefined]
使数组可迭代。注意:null更常见的是apply的第一个arg但是0更短。Object.keys(Array.apply(0,Array(3))) // ['0', '1', '2']
然后获取数组的键(因为Arrays是typeof数组是一个带键索引的对象。Object.keys(Array.apply(0,Array(3))).map(Number) // [0, 1, 2]
并映射键,将字符串转换为数字。答案 33 :(得分:7)
使用ES6
const generateArray = n => [...Array(n)].map((_, index) => index + 1);
答案 34 :(得分:7)
以下函数返回一个填充了数字的数组:
var createArrayOfNumbers = function (n) {
return Array.apply(null, new Array(n)).map(function (empty, index) {
return index;
});
};
请注意,使用数组构造函数创建的数组由空洞组成,因此无法使用map等数组函数遍历它。因此使用Array.apply
函数。
答案 35 :(得分:7)
您可以使用函数生成器或函数*表达式。 这是[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function ]以及对[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function ]的函数生成器链接的引用。
let a = 1, b = 10;
function* range(a, b) {
for (var i = a; i <= b; ++i) yield i;
}
Array.from(range(a, b));
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[...range(a, b)]
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
答案 36 :(得分:6)
我一直在寻找一个功能解决方案,我最终得到了:
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(',')
将稀疏数组转换为连续数组。
答案 37 :(得分:6)
Array(...Array(9)).map((_, i) => i);
console.log(Array(...Array(9)).map((_, i) => i))
答案 38 :(得分:6)
答案 39 :(得分:6)
即兴创作:
var range = function (n) {
return Array(n).join().split(',').map(function(e, i) { return i; });
}
可以获得以下选项:
1)Array.init to value v
var arrayInitTo = function (n,v) {
return Array(n).join().split(',').map(function() { return v; });
};
2)获得相反的范围:
var rangeRev = function (n) {
return Array(n).join().split(',').map(function() { return n--; });
};
答案 40 :(得分:6)
我没有看到任何基于递归函数的解决方案(并且从未编写过递归函数)所以这是我的尝试。
请注意,array.push(something)返回数组的新长度:
(a=[]).push(a.push(a.push(0))) // a = [0, 1, 2]
使用递归函数:
var a = (function f(s,e,a,n){return ((n?n:n=s)>e)?a:f(s,e,a?a:a=[],a.push(n)+s)})(start,end) // e.g., start = 1, end = 5
编辑:另外两个解决方案
var a = Object.keys(new Int8Array(6)).map(Number).slice(1)
和
var a = []
var i=setInterval(function(){a.length===5?clearInterval(i):a.push(a.length+1)})
答案 41 :(得分:5)
您可以使用Es6中的数组填充和映射;就像一些人在回答这个问题时提出的建议一样。以下是一些示例:
Example-One: Array(10).fill(0).map((e,i)=>i+1)
Result-One: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Example-Two: Array(100/10).fill(0).map((e,i)=>(i*10)+10)
Result-Two:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
我更喜欢这样做,因为我发现它简单直接。
答案 42 :(得分:5)
从 1 开始:
[...Array(31).keys()].map(a=>a+1)
答案 43 :(得分:4)
Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
答案 44 :(得分:4)
我找到了这个旧线程,因为我自己也在想这个问题,但我猜这里没有一个答案比原来的例子更容易,正如科科多科评论的那样,哈哈!
我自己最终使用了这个方法:
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)
可能会更快。
答案 45 :(得分:3)
试试这个
[...Array.from({length:30}).keys()]
答案 46 :(得分:3)
让我们分享我的:p
var i = 10;
Math.pow(2, i).toString(2).split('').map((i,j) => j)
答案 47 :(得分:3)
基于高票答案及其高票评论。
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 ]
答案 48 :(得分:3)
尝试在Number&#39的原型中添加iterator。
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...of loops。
for(const number of 10) console.log(number);//logs 0 through 9 sequentially
它有点令人费解,但也很酷。
答案 49 :(得分:3)
尝试一下
const foo = numberOfItems=> [...Array(numberOfItems).keys()].map(i => i+1);
答案 50 :(得分:2)
为了好玩,我想建立 Ian Henry's answer 。
当然var array = new Array(N);
将为您提供一个大小为N
的数组,但键和值将相同....然后将数组缩短为M
大小,请使用{ {1}} ....但是对于一些附加功能,请尝试:
array.length = M
以上输出:
1是项目:1 of 12
-7.5是项目:2 of 12
-16是项目:3 of 12
-24.5是项目:4 of 12
-33是项目:5 of 12
-41.5是项目:6 of 12
-50是项目:7 of 12
-58.5是项目:8 of 12
-67是项目:9 of 12
-75.5是项目:10 of 12
-84是项目:11 of 12
-92.5是项目:12 of 12
此功能使用自动生成的 arguments
数组。
该函数创建一个数组,其中填充的值从function range()
{
// This function takes optional arguments:
// start, end, increment
// start may be larger or smaller than end
// Example: range(null, null, 2);
var array = []; // Create empty array
// Get arguments or set default values:
var start = (arguments[0] ? arguments[0] : 0);
var end = (arguments[1] ? arguments[1] : 9);
// If start == end return array of size 1
if (start == end) { array.push(start); return array; }
var inc = (arguments[2] ? Math.abs(arguments[2]) : 1);
inc *= (start > end ? -1 : 1); // Figure out which direction to increment.
// Loop ending condition depends on relative sizes of start and end
for (var i = start; (start < end ? i <= end : i >= end) ; i += inc)
array.push(i);
return array;
}
var foo = range(1, -100, 8.5)
for(var i=0;i<foo.length;i++){
document.write(foo[i] + ' is item: ' + (i+1) + ' of ' + foo.length + '<br/>');
}
开始,以start
结尾,增量为{{1}},其中
end
每个值都有一个默认值,增量的符号无关紧要,因为增量的方向取决于开始和结束的相对大小。
答案 51 :(得分:2)
所有这些都太复杂了。只是做:
function count(num) {
var arr = [];
var i = 0;
while (num--) {
arr.push(i++);
}
return arr;
}
console.log(count(9))
//=> [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]
或者执行从a
到b
function range(a, b) {
var arr = [];
while (a < b + 1) {
arr.push(a++);
}
return arr;
}
console.log(range(4, 9))
//=> [ 4, 5, 6, 7, 8, 9 ]
答案 52 :(得分:2)
js否为100个数组
// string arr
const arr = [...``.padStart(100, ` `)].map((item, i) => i + 1 + ``);
// (100) ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100"]
// number arr
const arr = [...``.padStart(100, ` `)].map((item, i) => i + 1);
// (100) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
Uint8Array
// number arr
const arr = new Uint8Array(100).map((item, i) => i + 1);
// Uint8Array(100) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
// string arr
const arr = [...new Uint8Array(100).map((item, i) => i + 1)].map((item, i) => i + 1 + ``);
// (100) ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100"]
答案 53 :(得分:2)
问题是替代这个技术,但我想分享更快这样做的方式。它与问题中的代码几乎完全相同,但它分配内存而不是使用push:
function range(n) {
let a = Array(n);
for (let i = 0; i < n; a[i++] = i);
return a;
}
答案 54 :(得分:2)
我可以生成的代码最少:
for(foo=[x=100]; x; foo[x-1]=x--);
console.log(foo);
答案 55 :(得分:2)
4
abcd
bcda
cdab
dabc
答案 56 :(得分:2)
ES5版本,效率低下,但可能是最短的表达式,而不是某些语句,其中变量用例如填充。一个this.myDate = moment().format()
循环:
for
答案 57 :(得分:2)
// A solution where you do not allocate a N sized array (ES6, with some flow annotation):
function* zeroToN(N /* : number */)/* : Generator<number, void, empty> */ {
for (let n = 0; n <= N; n += 1) yield n;
}
// With this generation, you can have your array
console.log([...zeroToN(10-1)])
// but let's define a helper iterator function
function mapIterator(iterator, mapping) {
const arr = [];
for (let result = iterator.next(); !result.done; result = iterator.next()) {
arr.push(mapping(result.value));
}
return arr;
}
// now you have a map function, without allocating that 0...N-1 array
console.log(mapIterator(zeroToN(10-1), n => n*n));
答案 58 :(得分:1)
嗯,简单而重要的问题。功能JS肯定缺少Array对象下的通用展开方法,因为我们可能需要创建一个数字项数组,不仅简单[1,2,3,...,111]
,而且函数产生的系列可能像x => x*2
而不是x => x
{1}}
目前,要执行此工作,我们必须依赖Array.prototype.map()
方法。但是,为了使用Array.prototype.map()
,我们需要提前知道数组的大小。好吧..如果我们不知道大小,那么我们可以使用Array.prototype.reduce()
,但Array.prototype.reduce()
旨在减少(折叠)不展开的权利..?
显然我们需要一个功能JS的Array.unfold()
工具。这是我们可以简单地实现自己的东西;
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.push(f(v)),runner(t(v)), res);
return runner(s);
};
Arrays.unfold(p,f,t,v)
有4个参数。
p
函数需要3个参数,就像许多数组函子一样。值,索引和当前结果数组。它应返回一个布尔值。当它返回true
时,递归迭代停止。f
计算索引0的舒适座位的种子值。因此,如果我们打算创建一个充满1,4,9,16,25 ...... n ^ 2等系列的数组,我们可以这样做。
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.push(f(v)),runner(t(v)), res);
return runner(s);
};
var myArr = Array.unfold((_,i) => i >= 9, x => Math.pow(x,2), x => x+1, 1);
console.log(myArr);
&#13;
答案 59 :(得分:1)
以下是摘要(在控制台中运行):
// setup:
var n = 10000000;
function* rangeIter(a, b) {
for (let i = a; i <= b; ++i) yield i;
}
function range(n) {
let a = []
for (; n--; a[n] = n);
return a;
}
function sequence(max, step = 1) {
return {
[Symbol.iterator]: function* () {
for (let i = 1; i <= max; i += step) yield i
}
}
}
var t0, t1, arr;
// tests
t0 = performance.now();
arr = Array.from({ length: n }, (a, i) => 1)
t1 = performance.now();
console.log("Array.from({ length: n }, (a, i) => 1) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = range(n);
t1 = performance.now();
console.log("range(n) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(rangeIter(0, n));
t1 = performance.now();
console.log("Array.from(rangeIter(0, n)) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...rangeIter(0, n)];
t1 = performance.now();
console.log("[...rangeIter(0, n)] Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(sequence(n));
t1 = performance.now();
console.log("Array.from(sequence(n)) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...sequence(n)];
t1 = performance.now();
console.log("[...sequence(n)] Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array(n).fill(0).map(Number.call, Number);
t1 = performance.now();
console.log("Array(n).fill(0).map(Number.call, Number) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(Array(n).keys());
t1 = performance.now();
console.log("Array.from(Array(n).keys()) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...Array(n).keys()];
t1 = performance.now();
console.log("[...Array(n).keys()] Took " + (t1 - t0) + " milliseconds.");
最快的是Array(n).fill(0).map(Number.call,Number),第二个是[... Array(n).keys()]
但是'... rangeIter'方法非常方便(可以内联),快速且功能强大
答案 60 :(得分:1)
使用递归的ES6解决方案。与所有其他解决方案不同
const range = (n, A = []) => (n === 1) ? [n, ...A] : range(n - 1, [n, ...A]);
console.log(range(5));
答案 61 :(得分:1)
获取在min,max之间具有n个随机数的数组(尽管不是唯一的)
function callItWhatYouWant(n, min, max) {
return Array.apply(null, {length: n}).map(Function.call, function(){return Math.floor(Math.random()*(max-min+1)+min)})
}
答案 62 :(得分:1)
此解决方案可能是最快的(使用20多个其他解决方案here进行速度测试)-它受lodash _.range函数的启发(但我更简单,更快捷)
let N = 10;
let a = Array(N), i = 0;
while(i<N) a[i++]=i;
// test
console.log(a);
基于while/for
的当前(2020.12.11)现有答案的性能优势:
a=Array(N)
开始分配一次内存i++
看起来比减少索引i--
快30%(可能是因为CPU高速缓存向前存储速度更快)答案 63 :(得分:0)
由于有很多好的答案,这也可能是一个选择,您也可以使用以下代码创建一个函数,该函数适用于任何数字组合
const start = 10;
const end = 30;
const difference = Math.abs(start-end);
const rangeArray = new Array(difference + 1).fill(undefined).map((val, key) => {
return start > end ? start - key : start + key;
})
答案 64 :(得分:0)
/**
* 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;
};
答案 65 :(得分:0)
a = Object.keys( [].fill.call({length:7}, '' ) ).map(Number)
a.pop();
console.debug(a)
[0,1,2,3,4,5,6]
答案 66 :(得分:0)
'_'.repeat(5).split('').map((_, i) => i + 1)
将产生[1, 2, 3, 4, 5]
答案 67 :(得分:0)
今天2020.12.11,我针对选定解决方案在Chrome v87,Safari v13.1.2和Firefox v83的MacOs HighSierra 10.13.6上进行了测试。
对于所有浏览器
while
)最快(除了适用于大N的Firefox之外,但它的速度很快)我执行2个测试用例:
以下摘要介绍了所有经过测试的解决方案A B C D E F G H I J K L M N O P Q R S T U V W X
function A(N) {
return Array.from({length: N}, (_, i) => i + 1)
}
function B(N) {
return Array(N).fill().map((_, i) => i+1);
}
function C(N) {
return Array(N).join().split(',').map((_, i) => i+1 );
}
function D(N) {
return Array.from(Array(N), (_, i) => i+1)
}
function E(N) {
return Array.from({ length: N }, (_, i) => i+1)
}
function F(N) {
return Array.from({length:N}, Number.call, i => i + 1)
}
function G(N) {
return (Array(N)+'').split(',').map((_,i)=> i+1)
}
function H(N) {
return [ ...Array(N).keys() ].map( i => i+1);
}
function I(N) {
return [...Array(N).keys()].map(x => x + 1);
}
function J(N) {
return [...Array(N+1).keys()].slice(1)
}
function K(N) {
return [...Array(N).keys()].map(x => ++x);
}
function L(N) {
let arr; (arr=[ ...Array(N+1).keys() ]).shift();
return arr;
}
function M(N) {
var arr = [];
var i = 0;
while (N--) arr.push(++i);
return arr;
}
function N(N) {
var a=[],b=N;while(b--)a[b]=b+1;
return a;
}
function O(N) {
var a=Array(N),b=0;
while(b<N) a[b++]=b;
return a;
}
function P(N) {
var foo = [];
for (var i = 1; i <= N; i++) foo.push(i);
return foo;
}
function Q(N) {
for(var a=[],b=N;b--;a[b]=b+1);
return a;
}
function R(N) {
for(var i,a=[i=0];i<N;a[i++]=i);
return a;
}
function S(N) {
let foo,x;
for(foo=[x=N]; x; foo[x-1]=x--);
return foo;
}
function T(N) {
return new Uint8Array(N).map((item, i) => i + 1);
}
function U(N) {
return '_'.repeat(5).split('').map((_, i) => i + 1);
}
function V(N) {
return _.range(1, N+1);
}
function W(N) {
return [...(function*(){let i=0;while(i<N)yield ++i})()]
}
function X(N) {
function sequence(max, step = 1) {
return {
[Symbol.iterator]: function* () {
for (let i = 1; i <= max; i += step) yield i
}
}
}
return [...sequence(N)];
}
[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X].forEach(f=> {
console.log(`${f.name} ${f(5)}`);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
这是铬的示例结果
答案 68 :(得分:0)
对于小范围,切片很好。 N仅在运行时已知,因此:
[0, 1, 2, 3, 4, 5].slice(0, N+1)
答案 69 :(得分:0)
有小功能,它允许使用像 [1,2]。范围(3,4) - &gt; [1,2,3,4]它也适用于负参数。享受。
Array.prototype.range = function(from, to)
{
var range = (!to)? from : Math.abs(to - from) + 1, increase = from < to;
var tmp = Array.apply(this, {"length": range}).map(function()
{
return (increase)?from++ : from--;
}, Number);
return this.concat(tmp);
};
答案 70 :(得分:-2)
Azle 有一个名为 create_array 的实用程序功能,它为您提供许多选择:
创建一个从0到5的数组:
az.create_array(0, 5)
[0,1,2,3,4,5
创建1到5之间的数组:
az.create_array(1, 5)
[1、2、3、4、5]
创建由5个数组组成的数组:
az.create_array(1, 5, ['apples','carrots','oranges'])
[ [“苹果”,“胡萝卜”,“橙色”], [“苹果”,“胡萝卜”,“橙色”], [“苹果”,“胡萝卜”,“橙色”], [“苹果”,“胡萝卜”,“橙色”], [“苹果”,“胡萝卜”,“橙色”] ]
创建由5个对象组成的数组:
az.create_array(1, 5, {"color" : "orangered"})
[{color:“ orangered”}}, {color:“ orangered”}, {color:“ orangered”}, {color:“ orangered”}, {color:“ orangered”}]
创建一个由6个随机数组成的数组:
az.create_array(0,5,'random') // default draws from 10
[9,5,4,6,9,7]
创建一个由1000个随机数字组成的 6个随机数数组:
az.create_array(0,5,'random', 1000)
[180,372,678,142,314,438]
这里是FIDDLE