执行 < something > N times (声明性语法)

在 Javascript 中有没有一种方法可以很容易地编写这样的代码:

[1,2,3].times do {
something();
}

任何可能支持类似语法的库?

更新: 以澄清-我希望对每个数组元素迭代分别调用 something()1、2和3次

211832 次浏览

只需使用 for循环:

var times = 10;


for(var i = 0; i < times; i++){
doSomething();
}
var times = [1,2,3];


for(var i = 0; i < times.length;  i++) {
for(var j = 0; j < times[i];j++) {
// do something
}
}

使用 jQuery .each()

$([1,2,3]).each(function(i, val) {
for(var j = 0; j < val;j++) {
// do something
}
});

或者

var x = [1,2,3];


$(x).each(function(i, val) {
for(var j = 0; j < val;j++) {
// do something
}
});

剪辑

你可以像下面这样使用纯 JS:

var times = [1,2,3];
times.forEach(function(i) {
// do something
});

只需使用嵌套循环(可能包含在函数中)

function times( fct, times ) {
for( var i=0; i<times.length; ++i ) {
for( var j=0; j<times[i]; ++j ) {
fct();
}
}
}

那就这么说吧:

times( doSomething, [1,2,3] );

你可以利用

Array.forEach

例如:

function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements)

或者使用 jQuery

$.each([52, 97], function(index, value) {
alert(index + ': ' + value);
});

Http://api.jquery.com/jquery.each/

既然你提到了强调:

假设要调用的函数是 f:

_.each([1,2,3], function (n) { _.times(n, f) });

例如,使用 f = function (x) { console.log(x); },您可以在控制台上: 0 0 1 0 1 2

times = function () {
var length = arguments.length;
for (var i = 0; i < length ; i++) {
for (var j = 0; j < arguments[i]; j++) {
dosomthing();
}
}
}

你可以这样说:

times(3,4);
times(1,2,3,4);
times(1,3,5,7,9);

如果不能使用 Underscorejs,可以自己实现它。通过将新方法附加到 Number 和 String 原型,您可以这样做(使用 ES6箭头函数) :

// With String
"5".times( (i) => console.log("number "+i) );


// With number variable
var five = 5;
five.times( (i) => console.log("number "+i) );


// With number literal (parentheses required)
(5).times( (i) => console.log("number "+i) );

您只需要创建一个函数表达式(不管名称是什么) ,并将其分配给您希望访问它的任何属性名(在原型上) :

var timesFunction = function(callback) {
if (typeof callback !== "function" ) {
throw new TypeError("Callback is not a function");
} else if( isNaN(parseInt(Number(this.valueOf()))) ) {
throw new TypeError("Object is not a valid number");
}
for (var i = 0; i < Number(this.valueOf()); i++) {
callback(i);
}
};


String.prototype.times = timesFunction;
Number.prototype.times = timesFunction;

这个答案是基于 Array.forEach的,没有任何库,只有原生的 香草味的

基本上要调用 something()3次,使用:

[1,2,3].forEach(function(i) {
something();
});

考虑到以下职能:

function something(){ console.log('something') }

产出将是:

something
something
something

为了完成这个问题,这里有一个分别调用 something()1、2和3次的方法:

现在是2017年,你可以使用 ES6:

[1,2,3].forEach(i => Array(i).fill(i).forEach(_ => {
something()
}))

或者用老式的 ES5:

[1,2,3].forEach(function(i) {
Array(i).fill(i).forEach(function() {
something()
})
}))

在这两种情况下,输出都是

产出将是:

something


something
something


something
something
something

(一次,两次,三次)

// calls doSomething 42 times
Array( 42 ).join( "x" ).split( "" ).forEach( doSomething );

还有

// creates 42 somethings
var somethings = Array( 42 ).join( "x" ).split( "" ).map( () => buildSomething(); );

或(透过 https://stackoverflow.com/a/20066663/275501)

Array.apply(null, {length: 42}).forEach( doSomething );

浪荡:

_.each([1, 2, 3], (item) => {
doSomeThing(item);
});


//Or:
_.each([1, 2, 3], doSomeThing);

或者如果你想 做某事 N 次:

const N = 10;
_.times(N, () => {
doSomeThing();
});


//Or shorter:
_.times(N, doSomeThing);

可能的 ES6替代品。

Array.from(Array(3)).forEach((x, i) => {
something();
});

而且,如果你想让它“分别被调用1、2和3次”。

Array.from(Array(3)).forEach((x, i) => {
Array.from(Array(i+1)).forEach((x, i2) => {
console.log(`Something ${ i } ${ i2 }`)
});
});

更新:

取自 未定义的填充数组

这似乎是创建初始数组的一种更优化的方法,我还更新了它,使用@Felix-eve 建议的第二个参数映射函数。

Array.from({ length: 3 }, (x, i) => {
something();
});

这些答案都很好,IMO@Andreas 是最好的,但是在 JS 中,很多时候我们必须异步地做事情,在这种情况下,异步已经涵盖了:

Http://caolan.github.io/async/docs.html#times

const async = require('async');


async.times(5, function(n, next) {
createUser(n, function(err, user) {
next(err, user);
});
}, function(err, users) {
// we should now have 5 users
});

这些“ times”特性对于大多数应用程序代码来说并不是非常有用,但是对于测试来说应该是非常有用的。

const loop (fn, times) => {
if (!times) { return }
fn()
loop(fn, times - 1)
}


loop(something, 3)

给定一个函数 something:

function something() { console.log("did something") }

Array原型机上增加了一种新的 times方法:

Array.prototype.times = function(f){
for(v of this)
for(var _ of Array(v))
f();
}

这个代码:

[1,2,3].times(something)

输出结果如下:

did something
did something
did something
did something
did something
did something

哪一个我 好好想想回答你更新的问题(5年后) ,但我不知道如何有用,这是一个阵列的工作?这样的效果是不是和调用 [6].times(something)一样呢? [6].times(something)可以写成:

for(_ of Array(6)) something();

(尽管如果使用 _作为垃圾变量,可能会损坏 loash 或下划线)

最简单的方法是通过 解构阵列,

如果项目的值没有设置,则自动为每个项目设置 设置 undefined:

[...Array(5)].map((item, i) => console.log(item, i))

The keys Array method can also be used to generate an Array of indices values:

[...Array(3).keys()] // [0, 1, 2]

或者,在使用 map之前,用 undefined创建一个 Array 和 fill所有项目:

为什么 map跳过从未定义的数组项

Something Array.fill没有强大的 IE 支持

Array(5).fill().map((item, i) => console.log(item, i))


If you want to make the above more "declarative", my currently opinion-based solution would be:

const iterate = times => callback => [...Array(times)].map((n,i) => callback(i))


iterate(3)(console.log)


使用老式(反向)循环:

// run 5 times:
for( let i=5; i--; )
console.log(i) 

或者作为一个声明性的 “同时”:

const run = (cb, ...args) => count => { while(count--) cb(...args) }


// executes the callback with whatever arguments, 3 times
run(console.log, 1,2,3)(3)

数组 from (ES6)

function doSomthing() {
...
}

像这样使用它:

Array.from(Array(length).keys()).forEach(doSomthing);

或者

Array.from({ length }, (v, i) => i).forEach(doSomthing);

或者

// array start counting from 1
Array.from({ length }, (v, i) => ++i).forEach(doSomthing);

使用 Array.from.forEach

let length = 5;
Array.from({length}).forEach((v, i) => {
console.log(`#${i}`);
});

有一个叫做 Ramda 的奇妙的库,它类似于 Underscore 和 Lodash,但是更强大。

const R = require('ramda');


R.call(R.times(() => {
console.log('do something')
}), 5);

Ramda 包含许多有用的函数

假设我们可以使用一些 ES6语法,比如传播运算符,我们将需要执行集合中所有数字之和的次数。

在这种情况下,如果次数等于 [1,2,3],那么总次数将是6,即1 + 2 + 3。

/**
* @param {number[]} times
* @param {cb} function
*/
function doTimes(times, cb) {
// Get the sum of all the times
const totalTimes = times.reduce((acc, time) => acc + time);
// Call the callback as many times as the sum
[...Array(totalTimes)].map(cb);
}


doTimes([1,2,3], () => console.log('something'));
// => Prints 'something' 6 times

如果构造和传播数组背后的逻辑不明显,这篇文章应该是 很有帮助

您还可以像下面这样对解构进行同样的操作

[...Array(3)].forEach( _ => console.log('do something'));

或者如果你需要索引

[...Array(3)].forEach(( _, index) => console.log('do something'));

实现:

对于那些对如何以类型安全的方式实现 String.timesNumber.times并与 thisArg协同工作感兴趣的人来说,这里是:

declare global {
interface Number {
times: (callbackFn: (iteration: number) => void, thisArg?: any) => void;
}
interface String {
times: (callbackFn: (iteration: number) => void, thisArg?: any) => void;
}
}


Number.prototype.times = function (callbackFn, thisArg) {
const num = this.valueOf()
if (typeof callbackFn !== "function" ) {
throw new TypeError("callbackFn is not a function")
}
if (num < 0) {
throw new RangeError('Must not be negative')
}
if (!isFinite(num)) {
throw new RangeError('Must be Finite')
}
if (isNaN(num)) {
throw new RangeError('Must not be NaN')
}


[...Array(num)].forEach((_, i) => callbackFn.bind(thisArg, i + 1)())
// Other elegant solutions
// new Array<null>(num).fill(null).forEach(() => {})
// Array.from({length: num}).forEach(() => {})
}


String.prototype.times = function (callbackFn, thisArg) {
let num = parseInt(this.valueOf())
if (typeof callbackFn !== "function" ) {
throw new TypeError("callbackFn is not a function")
}
if (num < 0) {
throw new RangeError('Must not be negative')
}
if (!isFinite(num)) {
throw new RangeError('Must be Finite')
}
// num is NaN if `this` is an empty string
if (isNaN(num)) {
num = 0
}


[...Array(num)].forEach((_, i) => callbackFn.bind(thisArg, i + 1)())
// Other elegant solutions
// new Array<null>(num).fill(null).forEach(() => {})
// Array.from({length: num}).forEach(() => {})
}

一个链接到 运动场的一些例子可以找到 给你

本职位实施解决方案张贴由: Andreas Bergström乙烯基Ozay Duman,和 SeregPie

我只是想补充一下,有一个叫做 .repeat(n)的很棒的 JS 方法,它会重复字符串 n’多次。所以如果你想找个东西重复字符串 n 次..。

function repeatString (number, string) {
return string.repeat(number);
}

所以如果你知道..。

repeatString(3, 'Hey there! ');

你会得到: “嘿,你好! 嘿,你好!”

就一会儿怎么样。

let times = 5;


while (times--) {


console.log(times+1)


}

参考文献: 假的减价(——)


编辑 : 如果有可能在其他地方操纵 times,使用 times-- > 0而不是 times--更安全,以防止 times低于 0时出现无限循环