Existe-t-il un moyen en Javascript d’écrire facilement quelque chose comme ceci:
[1,2,3].times do {
something();
}
Toute bibliothèque qui pourrait supporter une syntaxe similaire peut-être?
Mise à jour: à préciser - J'aimerais que something()
soit appelé 1,2 et 3 fois respectivement pour chaque itération d'élément de tableau
Cette réponse est basée sur Array.forEach
, sans aucune bibliothèque, juste native Vanilla .
Pour appeler fondamentalement something()
3 fois, utilisez:
[1,2,3].forEach(function(i) {
something();
});
compte tenu de la fonction suivante:
function something(){ console.log('something') }
La sortie sera
something
something
something
Pour compléter ces questions, voici une façon de téléphoner à something()
1, 2 et 3 fois respectivement:
[1,2,3].forEach(i => Array(i).fill(i).forEach(_ => {
something()
}))
[1,2,3].forEach(function(i) {
Array(i).fill(i).forEach(function() {
something()
})
}))
Dans les deux cas, la sortie sera
La sortie sera
something
something
something
something
something
something
(une fois, puis deux fois, puis trois fois)
Il suffit d'utiliser une boucle:
var times = 10;
for(var i=0; i < times; i++){
doSomething();
}
Alternative ES6 possible.
Array.from(Array(3)).forEach((x, i) => {
something();
});
Et, si vous voulez "être appelé respectivement 1,2 et 3 fois".
Array.from(Array(3)).forEach((x, i) => {
Array.from(Array(i+1)).forEach((x, i2) => {
console.log(`Something ${ i } ${ i2 }`)
});
});
Tiré de filling-array-with-undefined
Cela semble être un moyen plus optimisé de créer le tableau initial.
Array.from({ length: 3 }).forEach((x, i) => {
something();
});
Puisque vous mentionnez Underscore:
En supposant que f
est la fonction que vous souhaitez appeler:
_.each([1,2,3], function (n) { _.times(n, f) });
fera l'affaire. Par exemple, avec f = function (x) { console.log(x); }
, vous obtiendrez sur votre console: 0 0 1 0 1 2
Nous pouvons utiliser lodash pour effectuer ce travail en:
_.each([1, 2, 3], function(item) {
doSomeThing(item);
});
//Or:
_.each([1, 2, 3], doSomeThing);
Ou si vous voulez faire quelque chose N fois:
var n = 10;
_.times(n, function() {
doSomeThing();
});
//Or:
_.times(n, doSomeThing);
Référence ce lien pour l'installation de lodash
Si vous ne pouvez pas utiliser Underscorejs, vous pouvez le mettre en œuvre vous-même. En associant de nouvelles méthodes aux prototypes Number et String, vous pouvez le faire comme ceci (en utilisant les fonctions de flèche 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) );
Vous devez simplement créer une expression de fonction (quel que soit le nom) et l'affecter au nom de la propriété (sur les prototypes) auquel vous souhaitez accéder, comme suit:
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;
fill
tous les éléments avec undefined
afin que map
méthode puisse fonctionner:
Array.fill
n'a pas de support IE
Array(5).fill().map(()=>{
// Do this 5 times:
console.log(111)
})
for( let i=5; i--; ){
// Do this 5 times:
console.log(222)
}
times = function () {
var length = arguments.length;
for (var i = 0; i < length ; i++) {
for (var j = 0; j < arguments[i]; j++) {
dosomthing();
}
}
}
Vous pouvez l'appeler comme ça:
times(3,4);
times(1,2,3,4);
times(1,3,5,7,9);
vous pouvez utiliser
Tableau.pour chaque
exemple:
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements)
ou avec jQuery
$.each([52, 97], function(index, value) {
alert(index + ': ' + value);
});
Il existe une bibliothèque fantastique appelée Ramda, similaire à Underscore et Lodash, mais plus puissante.
const R = require('ramda');
R.call(R.times(() => {
console.log('do something')
}), 5);
Ramda contient de nombreuses fonctions utiles. Voir Documentation Ramda
// calls doSomething 42 times
Array( 42 ).join( "x" ).split( "" ).forEach( doSomething );
et
// creates 42 somethings
var somethings = Array( 42 ).join( "x" ).split( "" ).map( () => buildSomething(); );
ou (via https://stackoverflow.com/a/20066663/275501 )
Array.apply(null, {length: 42}).forEach( doSomething );
var times = [1,2,3];
for(var i = 0; i < times.length; i++) {
for(var j = 0; j < times[i];j++) {
// do something
}
}
Utilisation de 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
}
});
Vous pouvez faire comme ci-dessous avec du JS pur:
var times = [1,2,3];
times.forEach(function(i) {
// do something
});
Vous pouvez utiliser length of array pour exécuter plusieurs fois votre tâche.
var arr = [1,2,3];
for(var i=0; i < arr.length; i++){
doSomething();
}
ou
var arr = [1,2,3];
do
{
}
while (i++ < arr.length);
Utilisez simplement une boucle imbriquée (peut-être incluse dans une fonction)
function times( fct, times ) {
for( var i=0; i<times.length; ++i ) {
for( var j=0; j<times[i]; ++j ) {
fct();
}
}
}
Puis appelez ça comme ça:
times( doSomething, [1,2,3] );
En supposant que nous puissions utiliser une syntaxe ES6 telle que l'opérateur spread, nous voudrons faire quelque chose autant de fois que la somme de tous les nombres de la collection.
Dans ce cas, si times est égal à [1,2,3]
, le nombre total de fois sera de 6, à savoir 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
Cet article devrait être utile si la logique derrière la construction et la propagation d’un tableau n’est pas évidente.
Ces réponses sont toutes bonnes et bonnes et IMO @Andreas est la meilleure, mais souvent dans JS, nous devons faire les choses de manière asynchrone.
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
});
Ces fonctionnalités "times" ne sont pas très utiles pour la plupart des applications, mais devraient être utiles pour les tests.
function doSomthing() {
...
}
Utilisez-le comme suit:
Array.from(Array(length).keys()).forEach(doSomthing);
Ou
Array.from({ length }, (v, i) => i).forEach(doSomthing);
Ou
// array start counting from 1
Array.from({ length }, (v, i) => ++i).forEach(doSomthing);
const loop (fn, times) => {
if (!times) { return }
fn()
loop(fn, times - 1)
}
loop(something, 3)
Utiliser Array.from
et .forEach
.
let length = 5;
Array.from({length}).forEach((v, i) => {
console.log(`#${i}`);
});