Do <something> N раз (декларативный синтаксис)
Есть ли способ в Javascript легко написать что-то подобное:
[1,2,3].times do {
something();
}
Любая библиотека, которая могла бы поддерживать какой-то подобный синтаксис, может быть?
Обновление:, чтобы уточнить. Я хотел бы, чтобы something()
назывался 1,2 и 3 раза соответственно для каждой итерации элемента массива
Ответы
Ответ 1
Этот ответ основан на 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 раза)
Ответ 2
Просто используйте цикл:
var times = 10;
for(var i=0; i < times; i++){
doSomething();
}
Ответ 3
Возможная альтернатива 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 }')
});
});
Обновление:
Взято из заполнения-массива-с-неопределенным
Это кажется более оптимизированным способом создания исходного массива.
Array.from({ length: 3 }).forEach((x, i) => {
something();
});
Ответ 4
Поскольку вы указываете Underscore:
Предполагая, что f
- это функция, которую вы хотите вызвать:
_.each([1,2,3], function (n) { _.times(n, f) });
сделает трюк. Например, с помощью f = function (x) { console.log(x); }
вы попадете на консоль:
0 0 1 0 1 2
Ответ 5
Мы можем использовать 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
установки
Ответ 6
Если вы не можете использовать 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;
Ответ 7
Создайте массив и fill
всех элементов с помощью undefined
, чтобы метод map
мог работать:
Array.fill
не поддерживает IE
Array(5).fill().map(()=>{
// Do this 5 times:
console.log(111)
})
Ответ 8
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
});
Ответ 9
Вы можете использовать длину массива для выполнения количества раз вашей задачи.
var arr = [1,2,3];
for(var i=0; i < arr.length; i++){
doSomething();
}
или
var arr = [1,2,3];
do
{
}
while (i++ < arr.length);
Ответ 10
вы можете использовать
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/
Ответ 11
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
// calls doSomething 42 times
Array( 42 ).join( "x" ).split( "" ).forEach( doSomething );
и
// creates 42 somethings
var somethings = Array( 42 ).join( "x" ).split( "" ).map( () => buildSomething(); );
или (через fooobar.com/questions/6812/...)
Array.apply(null, {length: 42}).forEach( doSomething );
Ответ 13
Вы можете использовать комбинацию подчеркивания /lodash range
с forEach
_.range(10).forEach(myFunc) // call myFunc 10 times
Ответ 14
Существует фантастическая библиотека под названием Ramda, которая похожа на Underscore и Lodash, но является более мощной.
const R = require('ramda');
R.call(R.times(() => {
console.log('do something')
}), 5);
Рамда содержит множество полезных функций. Смотрите документацию Ramda
Ответ 15
Вы также можете сделать то же самое с деструктурой, как показано ниже
[...Array(3)].forEach( _ => console.log('do something'));
или если вам нужен индекс
[...Array(3)].forEach(( _, index) => console.log('do something'));
Ответ 16
Просто используйте вложенный цикл (возможно, заключенный в функцию)
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] );
Ответ 17
Все эти ответы хороши и хороши, и IMO @Andreas - лучшая, но много раз в JS мы должны делать асинхронно, в этом случае async вы рассмотрели:
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
});
Эти функции "времени" очень полезны для большинства прикладных программ, но должны быть полезны для тестирования.
Ответ 18
const loop (fn, times) => {
if (!times) { return }
fn()
loop(fn, times - 1)
}
loop(something, 3)
Ответ 19
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);
Ответ 20
Использование Array.from
и .forEach
.
let length = 5;
Array.from({length}).forEach((v, i) => {
console.log('#${i}');
});
Ответ 21
Предполагая, что мы можем использовать некоторый синтаксис 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
Этот пост должен быть полезным, если логика создания и распространения массива не очевидна.
Ответ 22
Для функции something
:
function something() { console.log("did something") }
И новый прототип times
добавлен 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)
, который, в свою очередь, может быть записан как:
for(_ of Array(6)) something();
(хотя использование _
как нежелательной переменной, вероятно, будет clobber lodash или подчеркивание, если вы его используете)