javascript “重复n次”的成语?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18499935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 12:09:51  来源:igfitidea点击:

Idiom for "repeat n times"?

javascript

提问by kjo



EDIT:The votes to close are wrong. The accepted answer in Repeat Character N Timesis not applicable in general. E.g.:

编辑:关闭投票是错误的。重复字符 N 次中接受的答案一般不适用。例如:

>>> Array(3).map(Math.random)
[undefined, undefined, undefined]

The other two answers propose modifying a built-in class, a practice that I consider completely unacceptable.

另外两个答案建议修改内置类,我认为这种做法是完全不可接受的。



Here's one somewhat wasteful and impractical way to produce an array of 3 random numbers in JS:

这是在 JS 中生成 3 个随机数数组的一种有点浪费且不切实际的方法:

>>> [1, 1, 1].map(Math.random)
[0.6324464592887568, 0.5969209806782131, 0.7362755801487572]

The use of a dummy array (e.g. [1, 1, 1]) just so that one can call mapon it, is, for sufficiently large nboth wasteful (of memory) and impractical.

使用虚拟数组(例如[1, 1, 1])只是为了可以调用map它,对于足够大的n既浪费(内存)又不切实际。

What one would like would be something like a hypothetical:

人们想要的是一种假设:

>>> repeat(3, Math.random)
[0.21425955396598173, 0.00226050232425945, 0.45261888146445495]

What's the closest one can come to this in "pure JS"?

在“纯 JS”中,最接近这个的是什么?

(I'm aware of Underscore, but there's stuff in its API that makes no sense to me, such as interpretation of map, so I'm trying to avoid it.)

(我知道 Underscore,但它的 API 中有一些对我来说毫无意义的东西,例如 的解释map,所以我试图避免它。)

采纳答案by David Brown

Underscore.js has a timesfunction that does exactly what you want:

Underscore.js 有一个times函数,它完全符合你的要求:

_.times(3, Math.random)

If you don't want to use Underscore, you can just write your own timesfunction (copied and slightly simplified from the Underscore source):

如果您不想使用 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;
};

回答by Okku

It canbe done using Array.prototype.map, but the array can't be empty. Fillit first:

可以使用来完成Array.prototype.map,但数组不能为空。先填写

console.log(
    Array(3).fill().map(Math.random)
);

Explanation:

解释:

The new Array(3)constructor creates a sparse array(or "holey" array, as the V8 team calls them) with three holes in it and a length of three. This means that it's equivalent to [,,,], which creates [<empty>, <empty>, <empty>,](note JavaScript's trailing commas). Note that an empty slot, i.e. a hole is not the same as undefinedas an assigned value. undefinedis an actual value, whereas <empty>is just a gap in the array.

new Array(3)构造函数创建一个稀疏数组(或“多孔”阵列,作为V8团队称他们在其三个洞和三个长度。这意味着它等效于[,,,], 创建[<empty>, <empty>, <empty>,](注意 JavaScript 的尾随逗号)。请注意,空槽(即孔)与undefined指定值不同。undefined是一个实际值,而<empty>只是数组中的一个间隙。

Array.prototype.mapis called once for each element in the array. But, because an empty array has no assigned values, the callback doesn't get called at all. For example, [1,,2].map(v=>v*2)would give [2,,4]; the middle slot is skipped, as it has a gap there.

Array.prototype.map数组中的每个元素调用一次。但是,因为空数组没有赋值,所以根本不会调用回调。例如,[1,,2].map(v=>v*2)会给[2,,4]; 中间的插槽被跳过,因为它在那里有一个间隙。

Enter Array.prototype.fill(value, start?, end?): with only one argument, it fills every slot in the array with the specified value. Technically, the first parameter is not optional, but by omitting it, undefinedis used as the value. This is okay, because the value isn't being used anyway. This way Array(3).fill()gives us [undefined, undefined, undefined].

输入Array.prototype.fill(value, start?, end?):只有一个参数,它用指定的值填充数组中的每个插槽。从技术上讲,第一个参数不是可选的,但通过省略它,undefined用作值。这没关系,因为无论如何都不会使用该值。这种方式Array(3).fill()给了我们[undefined, undefined, undefined].

Now that the array has values in it, it can be mapped over, like seen above.

现在数组中有值,它可以被映射,如上所示。



You could also spreadthe empty arrayinto values of undefinedbefore mapping:

您还可以在映射之前将spreadarray转换为值undefined

console.log(
    [...Array(3)].map(Math.random)
);

Explanation:

解释:

Array operators introduced in ECMAScript2015 or newer threat holes in arrays as undefinedvalues. Array.prototype.mapwas introduced in ES5 (I.E. what preceded ES2015), where, confusingly, holes in arrays are to be skipped over, creating a little bit of inconsistency in JS Array functions depending on which edition of ECMAScript they were released in.

ECMAScript2015 中引入的数组运算符或数组中undefined更新的威胁漏洞作为Array.prototype.map是在 ES5 中引入的(即 ES2015 之前的版本),令人困惑的是,数组中的漏洞将被跳过,根据它们发布的 ECMAScript 版本,在 JS 数组函数中产生了一点点不一致。

The spread operator ...was introduced in ES2015, so as per spec, it converts any holes in the given array into values of undefined. In other words, [...Array(3)]gives us [undefined, undefined, undefined], just like Array(3).fill()did above.

扩展运算符...是在 ES2015 中引入的,因此根据规范,它将给定数组中的任何空洞转换为 的值undefined。换句话说,[...Array(3)]给了我们[undefined, undefined, undefined],就像Array(3).fill()上面一样。



Sometimes you may need to seed in numbers sequentially. As pointed out by Kevin Danikowski, Array.prototype.mapgives you that out of the box, as the second parameter is the current key:

有时您可能需要按顺序播种。正如Kevin Danikowski所指出的那样,Array.prototype.map为您提供开箱即用的功能,因为第二个参数是当前键:

const Fibonacci = n => Math.round(((5**.5 + 1) / 2)**n / 5**.5);

console.log(
    Array(10).fill().map((_, i) => Fibonacci(++i))
);

回答by Anona112

shortmost elegant ES6:

最短的优雅 ES6:

let times=(n,f)=>{while(n-->0)f();}

oh, That's not for creating an array, but it's still neat!

哦,那不是为了创建数组,但它仍然很整洁!

times(3,()=>print('wow'))

or Ruby style:

或 Ruby 风格:

Object.assign(Number.prototype,{times(f){x=this;while(x-->0)f();}})
3..times(()=>print('wow'))

回答by trincot

Maybe the Array.fromcallback can be of use:

也许Array.from回调可能有用:

var result = Array.from(Array(3), Math.random);

console.log(result);

There is a slight advantage here over using map: mapalready needs an array with all the entries(maybe created with fillor the spread syntax), to then create the final array from that. So in total a mapsolution will create nentries twice. Array.fromdoes not need an array with entries, just an object with a lengthproperty will do, and Array(3)is providing that.

与 using 相比,这里有一个小小的优势mapmap已经需要一个包含所有条目的数组(可能是用fill或 spread 语法创建的),然后从中创建最终数组。所以总的来说,一个map解决方案将创建n个条目两次Array.from不需要带有条目的数组,只需一个带有length属性的对象即可,并且Array(3)正在提供。

So depending on your preferences, the above can also be done like this:

所以根据你的喜好,上面的也可以这样完成:

var result = Array.from({length:3}, Math.random);

console.log(result);

Finally, if you would create a repeatfunction for this, you can name the argument lengthand use the ES6 short notation for object literals:

最后,如果您要为此创建一个repeat函数,您可以命名参数length并使用 ES6 短符号表示对象字面量:

const repeat = (length, cb) => Array.from({length}, cb);

const result = repeat(3, Math.random);
console.log(result);

回答by vinyll

A modern way to create that repeatfunction:

创建该repeat函数的现代方法:

repeat = (n, cb) => {[...Array(n)].forEach(cb)}

You can then use it with:

然后您可以将其用于:

repeat(3, _ => console.log(Math.random()))

Would output:

会输出:

0.6324464592887568
0.5969209806782131
0.7362755801487572

回答by Rafael Motta

I like this way:

我喜欢这种方式:

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