do <something> N बार (घोषित सिंटैक्स)


96

क्या जावास्क्रिप्ट में कुछ इस तरह से आसानी से लिखने का तरीका है:

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

कोई भी पुस्तकालय जो शायद कुछ इसी तरह के वाक्यविन्यास का समर्थन कर सकता है?

अद्यतन: स्पष्ट करने के लिए - मैं something()प्रत्येक सरणी तत्व पुनरावृत्ति के लिए क्रमशः 1,2 और 3 बार बुलाया जाना चाहूंगा


2
मैं कहूंगा कि जेएस में इस तरह की कोई सुविधा नहीं है, और यह शीर्ष 5 लापता सुविधा है। यह सॉफ्टवेयर के परीक्षण के लिए बहुत उपयोगी है, कुछ से भी अधिक।
अलेक्जेंडर मिल्स

जवाबों:


48

यह उत्तर 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

(एक बार, फिर दो बार, फिर 3 बार)


18
यह गलत है क्योंकि यह प्रश्न के इस भाग को संतुष्ट नहीं करता है: 'मैं कुछ () को 1,2 और 3 बार कहा जाना चाहूंगा'। इस कोड somethingका उपयोग केवल 3 बार कहा जाता है, इसे 6 बार कहा जाना चाहिए।
इयान न्यूजन

तब मुझे लगता है कि इसे सर्वश्रेष्ठ उत्तर के रूप में चुना गया है क्योंकि यह एक अच्छी क्लीनर शुरुआत हो सकती है।
vinyll

3
आप वास्तविक अनुक्रमित के लिए अपनी आवश्यकताओं के आधार पर भी उपयोग [...Array(i)]कर सकते हैं या Array(i).fill()कर सकते हैं।
गुइडो बोमन

यदि आप किसी भी तर्क में रुचि नहीं रखते हैं, तो उपयोग करें.forEach(something)
kvsm

88

बस एक लूप का उपयोग करें:

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

3
धन्यवाद! मैं एक घोषणात्मक वाक्य रचना (जैस्मीन आदि की तरह) से
लाभान्वित होना चाहूंगा

सही, लेकिन लूप डिक्लेयर सिंटैक्स के लिए एक कार्यात्मक भी बेहतर होगा
अलेक्जेंडर मिल्स

71

संभावित 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();
});

3
मुझे यह कहकर यह कहना चाहिए कि यह ठीक है यदि आप जल्दी से कुछ लिख रहे हैं, लेकिन प्रदर्शन भयानक है, तो इसका उपयोग गहन पुनरावृत्ति के लिए या संभवत: उत्पादन में न करें।
nverba

यदि आप ES6 के लिए जा रहे हैं, तो आप forEach () के बजाय मानचित्र () का उपयोग कर सकते हैं
एंडी फोर्ड

3
यदि थकाऊता लक्ष्य है (और वास्तव में, भले ही यह नहीं है), इसे कॉल करने के बजाय फ़ंक्शन पास करें:Array.from(Array(3)).forEach(something)
kvsm

1
प्रतिक्रिया अभिव्यक्ति के साथ ही काम करता है।
जोश शर्की

4
Array.from()एक वैकल्पिक दूसरा पैरामीटर है mapFn, जो आपको सरणी के प्रत्येक तत्व पर एक मानचित्र फ़ंक्शन को निष्पादित करने की अनुमति देता है, इसलिए forEach का उपयोग करने की कोई आवश्यकता नहीं है। आप बस कर सकते हैं:Array.from({length: 3}, () => somthing() )
फेलिक्स ईव

19

चूंकि आप अंडरस्कोर का उल्लेख करते हैं:

मान लें fकि वह फ़ंक्शन है जिसे आप कॉल करना चाहते हैं:

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

चाल चलेगा। उदाहरण के लिए, f = function (x) { console.log(x); }आपको अपने कंसोल पर मिलेगा: 0 0 1 0 1 2


वास्तव में, मुझे लगा कि आप अलगाव चाहते हैं।
गुंज़ाद

2
_(3).times(function(n){return n;});चाल चलनी चाहिए। यहां डॉक्स देखें।
चिप

18

साथ lodash :

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

का संदर्भ लें इस लिंक के लिए lodashस्थापना


14

एक सरणी बनाएँ और इतनी विधि के fillसाथ सभी आइटम काम कर सकते हैं:undefinedmap

Array.fill कोई IE समर्थन नहीं है

// run 5 times:
Array(5).fill().map((item, i)=>{ 
   console.log(i) // print index
})

यदि आप उपर्युक्त और अधिक "निर्णायक" बनाना चाहते हैं, तो मेरा वर्तमान में राय आधारित समाधान होगा:


पुराने स्कूल (रिवर्स) लूप का उपयोग करना:

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

या एक घोषणा के रूप में "जबकि" :


1
मन के टुकड़े के लिए मैंने एक uuid फ़ंक्शन को 50k बार चलाया, यह सुनिश्चित करने के लिए कि उसने कभी uuid डुप्लिकेट नहीं किया है। इसलिए मैंने टॉप लूप बनाम नीचे की तरफ सिर्फ किक के लिए, क्रोम क्रोम टूल्स का उपयोग करते हुए एक सामान्य पेज लोड के बीच में चल रहा है, अगर im गूंगा नहीं हो रहा है तो मुझे लगता है कि इसकी ~ 1.2 बिलियन की तुलना Array.indexOf () प्लस जेनरेट करने वाले अल्क यूयिड्स के उपयोग से होती है। newschool = 1st-5561.2ms 2nd-5426.8ms | oldschool = 1st-4966.3ms / 2nd-4929.0ms कहानी का नैतिक यदि आप बिलियन + रेंज में नहीं हैं, तो आपको इन 200, 1k, यहां तक ​​कि 10k बार कुछ करने के लिए चलने वाले अंतर पर ध्यान नहीं दिया जाएगा। लगा कि कोई मेरी तरह जिज्ञासु हो सकता है।
rifi2k

यह सही है और कई वर्षों से ज्ञात है। विभिन्न दृष्टिकोणों को गति लाभों के लिए नहीं बल्कि पुराने ब्राउज़रों के समर्थन के लिए प्रस्तुत किया गया था।
vsync

3
जाहिर है कि हर कोई इस धागे को पढ़ता है, जानता है कि आपने उनकी गति की तुलना करने के लिए उदाहरण प्रस्तुत नहीं किए हैं। मैं सिर्फ एक छोटे से परीक्षण चलाने के लिए उनका उपयोग करने के लिए हुआ और मुझे लगा कि मैं कुछ जानकारी साझा करूंगा, जो किसी भी व्यक्ति को दिलचस्प लग सकती है। मैं वास्तव में सही नहीं हूं क्योंकि मैं वास्तव में एक सवाल का जवाब नहीं दे रहा था, केवल जानकारी प्रदर्शित करने और एक अनुस्मारक देने के लिए एक लूप की गति को पसीना नहीं करने के लिए जब आपकी केवल कुछ चीजें कर रही थीं जो कि एक युगल एमएस में वैसे भी समाप्त हो जाएंगी। यह वास्तव में या तो ज्ञात नहीं है क्योंकि एक साल पहले एक ही टेस्ट यानी 50% धीमा हो सकता है क्योंकि ब्राउज़र हर समय बदलते रहते हैं।
rifi2k

10

आप निम्नानुसार विनाशकारी के साथ भी कर सकते हैं

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

या यदि आपको सूचकांक की आवश्यकता है

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

8

यदि आप अंडरस्कोरज का उपयोग नहीं कर सकते हैं, तो आप इसे स्वयं लागू कर सकते हैं। नंबर और स्ट्रिंग प्रोटोटाइप में नए तरीके संलग्न करके, आप इसे इस तरह से कर सकते हैं (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;

1
मुझे प्रोटोटाइप को पैच करने के लिए कितना खराब होना चाहिए, यह पुनर्निवेश करना होगा, लेकिन आमतौर पर यह ठीक है
अलेक्जेंडर मिल्स

2

रामाडा नामक एक शानदार पुस्तकालय है, जो अंडरस्कोर और लॉडश के समान है, लेकिन अधिक शक्तिशाली है।

const R = require('ramda');

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

रामदा में बहुत सारे उपयोगी कार्य हैं। रामदा प्रलेखन देखें


मैं इस पुस्तकालय को एक आधुनिक और सुरुचिपूर्ण एफपी समाधान के रूप में प्यार करता हूं।
मोमोको

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

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/


ऐसा लगता है forEachकि केवल IE में संस्करण 9 से समर्थित है: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Bruno

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

+1 - यह मापदंडों की चर राशियों के साथ फ़ंक्शन को कॉल करने के लिए मूल जावास्क्रिप्ट क्षमता का उपयोग करता है। किसी अतिरिक्त पुस्तकालय की आवश्यकता नहीं है। अच्छा समाधान
RustyTheBoyRobot


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

या

var x = [1,2,3];

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

संपादित करें

आप शुद्ध जेएस के साथ नीचे की तरह कर सकते हैं:

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

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

0

ये उत्तर सभी अच्छे हैं

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

ये 'बार' सुविधाएँ अधिकांश एप्लिकेशन कोड के लिए बहुत उपयोगी हैं, लेकिन परीक्षण के लिए उपयोगी होनी चाहिए।



0

एक समारोह दिया 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), जो बदले में लिखा जा सकता है:

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

(हालांकि _एक जंक चर के रूप में उपयोग संभवत: क्लोबर लॉश या अंडरस्कोर होगा यदि आप इसका उपयोग कर रहे हैं)


1
देशी जेएस ऑब्जेक्ट में कस्टम तरीकों को जोड़ने के लिए इसे बुरा अभ्यास माना जाता है।
लायर एलरोम

आप कम से कम के लिए बाहर लबादा बंद को रोकने के लिए के letरूप में उपयोग कर सकते हैं for (let _ of Array(6)) something()
सिरो सेंटिल्ली :08 冠状 iro 法轮功

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


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

यह पोस्ट सहायक होनी चाहिए अगर किसी सरणी को बनाने और फैलाने के पीछे तर्क स्पष्ट नहीं है।


0

टाइपस्क्रिप्ट कार्यान्वयन:

आप में से उन लोगों के लिए जो कैसे लागू करने में रुचि रखते हैं String.timesऔर Number.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(() => {})
}

कुछ उदाहरणों के साथ टाइपस्क्रिप्ट प्लेग्राउंड का लिंक यहां पाया जा सकता है

इस पोस्ट के समाधानों को पोस्ट किया गया है: एंड्रियास बर्गस्ट्रॉम , विनील , ओजाय दुमन , और सेरेगापी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.