做<something> N次(声明性语法)</something>

时间:2012-06-12 09:26:55

标签: javascript jquery underscore.js

Javascript中是否有办法轻松编写这样的内容:

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

任何可能支持某种类似语法的库都可以吗?

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

23 个答案:

答案 0 :(得分:63)

只需使用循环:

var times = 10;
for(var i=0; i < times; i++){
    doSomething();
}

答案 1 :(得分:34)

可能的ES6替代方案。

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

并且,如果你想要它&#34;分别被称为1,2和3&#34;。

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

更新

取自filling-arrays-with-undefined

这似乎是创建初始数组的更优化方式。

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

答案 2 :(得分:31)

此答案基于Array.forEach,没有任何库,只有原生vanilla

要基本上拨打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

(一次,然后两次,然后3次)

答案 3 :(得分:19)

因为你提到了下划线:

假设f是您要调用的函数:

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

会做到这一点。例如,使用f = function (x) { console.log(x); },您将进入控制台: 0 0 1 0 1 2

答案 4 :(得分:13)

我们可以通过以下方式使用lodash来完成这项工作:

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

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

或者,如果你想做N次

var n = 10;
_.times(n, function() {
   doSomeThing();
});

//Or: 
_.times(n, doSomeThing);

lodash安装

的参考this link

答案 5 :(得分: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;

答案 6 :(得分:5)

创建一个数组,并使用undefined fill所有项,以便map方法可以工作:

  

Array.fill不支持IE

Array(5).fill().map(()=>{ 
   // Do this 5 times:
   console.log(111) 
})


使用老式的reveres循环:

for( let i=5; i--; ){
   // Do this 5 times:
   console.log(222) 
}

答案 7 :(得分:3)

您还可以通过以下方式进行销毁

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

或者如果您需要索引

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

答案 8 :(得分:1)

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
  }
});

OR

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
});

答案 9 :(得分:1)

有一个很棒的库叫做Ramda,它类似于Underscore和Lodash,但是功能更强大。

const R = require('ramda');

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

Ramda包含许多有用的功能。参见Ramda documentation

答案 10 :(得分:1)

// 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 );

答案 11 :(得分:1)

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);

答案 12 :(得分:1)

你可以使用

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/

答案 13 :(得分:1)

您可以使用数组长度来执行任务的次数。

var arr = [1,2,3];

for(var i=0; i < arr.length; i++){
    doSomething();
}

 var arr = [1,2,3];

 do
 {


 }
 while (i++ < arr.length);

答案 14 :(得分:0)

这些答案都很好而且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
});

这些&#39;次&#39;功能对大多数应用程序代码都没有用,但对测试非常有用。

答案 15 :(得分:0)

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

loop(something, 3)

答案 16 :(得分:0)

Array.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);

答案 17 :(得分:0)

使用Array.from.forEach

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

答案 18 :(得分:0)

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

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] );

答案 19 :(得分:0)

假设我们可以使用诸如扩展运算符之类的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

如果构造和扩展数组的逻辑不明显,则该帖子应为helpful

答案 20 :(得分:0)

TypeScript实现:

对于那些对如何以安全类型且可与String.times配合使用的方式实现Number.timesthisArg的人来说,请继续:

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(() => {})
}

带有一些示例的 TypeScript游乐场的链接可以找到here

这篇文章实现了以下解决方案:安德烈亚斯·伯格斯特罗姆 vinyll Ozay Duman SeregPie

答案 21 :(得分:0)

我想补充一下,有一个很棒的 JS 方法,叫做 .repeat(n),它会重复字符串 'n' 次。因此,如果您正在寻找重复字符串 'n' 次的内容...

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

所以如果你...

repeatString(3, 'Hey there! ');

你会得到:'嘿!嘿!嘿! '

答案 22 :(得分:-1)

给定函数something

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

并在times原型中添加了一个新方法Array

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)相同,后者可以写成:{/ p>

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

(尽管使用_作为垃圾变量可能会破坏lodash或下划线(如果您正在使用它)