编辑:关闭的投票是错误的.重复字符N次中接受的答案通常不适用.例如:
>>> Array(3).map(Math.random)
[undefined, undefined, undefined]
Run Code Online (Sandbox Code Playgroud)
另外两个答案建议修改内置类,我认为这种做法完全不可接受.
这是在JS中生成3个随机数的数组有点浪费和不切实际的方法:
>>> [1, 1, 1].map(Math.random)
[0.6324464592887568, 0.5969209806782131, 0.7362755801487572]
Run Code Online (Sandbox Code Playgroud)
使用虚拟阵列(例如[1, 1, 1])以便人们可以对其进行调用map,对于足够大的n来说,既浪费(内存)又不实用.
人们想要的是一个假设:
>>> repeat(3, Math.random)
[0.21425955396598173, 0.00226050232425945, 0.45261888146445495]
Run Code Online (Sandbox Code Playgroud)
在"纯JS"中最接近的是什么?
(我知道Underscore,但是它的API中有些东西对我没有意义,比如解释map,所以我试图避免它.)
Okk*_*kku 56
它可以使用Array.prototype.map,但数组不能为空.首先填写:
console.log(
Array(3).fill().map(Math.random)
);Run Code Online (Sandbox Code Playgroud)
说明:
该new Array(3)构造函数创建一个稀疏数组(或"多孔"阵列,作为V8团队称他们)在其三个洞和三个长度.这意味着它等同于[,,,]创建[<empty>, <empty>, <empty>,](注意JavaScript的尾随逗号).
undefined为数组中的每个元素调用一次.但是,因为空数组没有赋值,所以根本不会调用回调.例如,undefined会给<empty>; 跳过中间位置.
输入Array.prototype.map:只有一个参数,它使用指定的值填充数组中的每个插槽.从技术上讲,第一个参数不是可选的,但通过省略它,[1,,2].map(v=>v*2)将用作值.这没关系,因为无论如何都没有使用该值.这种方式[2,,4]给了我们Array.prototype.fill(value, start?, end?).
现在数组中有值,它可以映射,如上所示.
您还可以在映射前undefined清空Array(3).fill()值[undefined, undefined, undefined]:
console.log(
[...Array(3)].map(Math.random)
);Run Code Online (Sandbox Code Playgroud)
说明:
ECMAScript2015中引入的数组运算符或数组中spread较新的威胁漏洞作为值.array在ES5(ES2015之前的 IE )中引入,其中令人困惑的是,数组中的漏洞将被跳过,在JS Array函数中产生一些不一致性,这取决于它们发布的ECMAScript版本.
扩展运算符undefined 是在ES2015中引入的,因此根据规范,它将给定数组中的任何空洞转换为值undefined.换句话说,Array.prototype.map给我们...,就像undefined上面所做的那样.
有时您可能需要按顺序播种数字.正如指出的凯文Danikowski,[...Array(3)]为您提供了开箱即用,作为第二个参数是当前的关键:
const Fibonacci = n => Math.round(((5**.5 + 1) / 2)**n / 5**.5);
console.log(
Array(10).fill().map((_, i) => Fibonacci(++i))
);Run Code Online (Sandbox Code Playgroud)
Dav*_*own 36
Underscore.js有一个时间函数,完全符合你的要求:
_.times(3, Math.random)
Run Code Online (Sandbox Code Playgroud)
如果您不想使用Underscore,您可以编写自己的times函数(从Underscore源复制并略微简化):
times = function(n, iterator) {
var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call();
return accum;
};
Run Code Online (Sandbox Code Playgroud)
Ano*_*112 15
最短的优雅ES6:
let times=(n,f)=>{while(n-->0)f();}
Run Code Online (Sandbox Code Playgroud)
哦,这不是用于创建阵列,但它仍然整洁!
times(3,()=>print('wow'))
Run Code Online (Sandbox Code Playgroud)
或Ruby风格:
Object.assign(Number.prototype,{times(f){x=this;while(x-->0)f();}})
3..times(()=>print('wow'))
Run Code Online (Sandbox Code Playgroud)
tri*_*cot 15
也许Array.from回调可以使用:
var result = Array.from(Array(3), Math.random);
console.log(result);Run Code Online (Sandbox Code Playgroud)
这里有一个小优势map:使用:map已经需要一个包含所有条目的数组(可能使用fill或扩展语法创建),然后从中创建最终数组.因此总的来说,map解决方案将创建两次n个条目.不需要带有条目的数组,只需要一个具有属性的对象,并提供它.Array.fromlengthArray(3)
所以根据你的喜好,上面也可以这样做:
var result = Array.from({length:3}, Math.random);
console.log(result);Run Code Online (Sandbox Code Playgroud)
最后,如果要为此创建repeat函数,可以为参数命名length并使用ES6短符号表示对象文字:
const repeat = (length, cb) => Array.from({length}, cb);
const result = repeat(3, Math.random);
console.log(result);Run Code Online (Sandbox Code Playgroud)
我喜欢这种方式:
[...Array(5).keys()].forEach(index =>
console.log(`do something ${index}`
)
Run Code Online (Sandbox Code Playgroud)
创建该repeat函数的现代方法:
repeat = (n, cb) => {[...Array(n)].forEach(cb)}
Run Code Online (Sandbox Code Playgroud)
然后您可以将其用于:
repeat(3, _ => console.log(Math.random()))
Run Code Online (Sandbox Code Playgroud)
会输出:
0.6324464592887568
0.5969209806782131
0.7362755801487572
Run Code Online (Sandbox Code Playgroud)