成语为"重复n次"?

kjo*_*kjo 43 javascript


编辑:关闭的投票是错误的.重复字符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)

  • 干得好,不需要添加npm包.另外,如果你想返回更复杂的东西,在你的地图中使用`.map((_,index)=> returnItem)` (3认同)

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)

  • downvote是因为有更多当前和更好的答案,投票更少. (4认同)

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)

  • 我想指出`n - > 0`不是某种箭头操作符,它是`n--> 0`.不过这很酷. (12认同)
  • 有趣的是你可以将"while(n - > 0)"读作"当n接近零"时,即使它在语义上不准确;) (6认同)
  • 如果你可以假设 `n` 是一个整数,你可以删除 `&gt;0` 检查,因为当 `n` 达到零时,它就等于 false。然而,非整数`n` 将导致无限循环。 (2认同)
  • 读完这个答案后,我觉得很愚蠢,不理解其中的一行:( (2认同)
  • 首先,@ koolaang创建了一个带有两个参数的函数,即n和f,n是整数,f是函数,并调用f次。 。(这是一个ES6箭头函数)在第二个实例中,他们采用“ Number.prototype”,它(所有)JavaScript数字都从其继承方法,并使用Object.assign为其添加一个名为“ times”的新方法。 。许多人会认为这是不好的做法:) (2认同)

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)


Raf*_*tta 5

我喜欢这种方式:

[...Array(5).keys()].forEach(index =>
  console.log(`do something ${index}`
)
Run Code Online (Sandbox Code Playgroud)

  • 这仅涵盖了问题的一半。这将如何用于做任何事情 5 次,而不仅仅是生成一个序列号。 (2认同)

vin*_*yll 5

创建该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)