कैसे underscore.js में _.each फ़ंक्शन को तोड़ना है


200

मैं underscore.js _.each()विधि के पुनरावृत्तियों को रोकने के लिए एक रास्ता खोज रहा हूं , लेकिन समाधान नहीं ढूंढ सकता। jQuery .each()यदि आप ऐसा तोड़ सकते हैं return false

क्या प्रत्येक को रेखांकित करने का एक तरीका है ()?

_([1,2,3]).each(function(v){
    if (v==2) return /*what?*/;
})

4
मुझे नहीं लगता कि यह संभव है, क्योंकि मूल forEachफ़ंक्शन यह सुविधा प्रदान नहीं करता है।
फेलिक्स क्लिंग

8
आम तौर पर eachएक बंद (अधिकांश भाषाओं में) का उपयोग करते समय , आप पहले अपनी सूची को फ़िल्टर करना चाहते हैं। इस तरह आपको इससे टूटने की चिंता नहीं करनी चाहिए। सामान्यतया, यदि आपको एक पुनरावृति से जल्दी तोड़ने की आवश्यकता है, तो संभवतः एक अलग तरीका है जो आप कर सकते हैं।
रॉब ह्रस्का 18

यहां ग्रूवी के लिए कुछ संबंधित प्रश्न हैं, जहां व्यवहार (एक eachबंद से आसानी से टूटने में असमर्थता ) जावास्क्रिप्ट के समान है।
रॉब ह्रस्का 18

@Dmitry_F, जैसा कि अन्य ने नोट किया है, आप वास्तव में वही नहीं कर सकते जो आप पूछ रहे हैं। लेकिन जैसा कि मैंने दिखाया, आप Array.everyजो व्यवहार चाहते हैं उसका अनुकरण करने के लिए उपयोग कर सकते हैं।
एस्क्रे

@Rob। चीयर्स। पहली टिप्पणी वास्तव में उपयोगी है। वास्तव में एक अलग तरीका था जो मैं कर सकता था।
net.uk.sweet

जवाबों:


267

आप eachविधि से नहीं तोड़ सकते हैं - यह मूल forEachविधि के व्यवहार का अनुकरण करता है , और देशी forEachलूप से बचने के लिए प्रदान नहीं करता है (अपवाद फेंकने के अलावा)।

हालांकि, सभी आशा खो नहीं है! आप Array.everyविधि का उपयोग कर सकते हैं । :)

उस लिंक से:

everycallbackसरणी में मौजूद प्रत्येक तत्व के लिए एक बार प्रदान किए गए फ़ंक्शन को तब तक निष्पादित करता है जब तक कि वह एक ऐसा स्थान न मिल जाए जहां callbackएक गलत मान लौटाया जाए। यदि ऐसा तत्व पाया जाता है, तो everyविधि तुरंत झूठी हो जाती है।

दूसरे शब्दों में, आप कुछ इस तरह से कर सकते हैं ( JSFiddle के लिए लिंक ):

[1, 2, 3, 4].every(function(n) {
    alert(n);
    return n !== 3;
});

यह सूचित करेंगे 1के माध्यम से 3, और फिर लूप से बाहर "तोड़"।

आप underscore.js का उपयोग कर रहे हैं, इसलिए आपको यह जानकर प्रसन्नता होगी कि यह एक विधि प्रदान करता हैevery -वे इसे कहते हैं every, लेकिन जैसा कि लिंक में उल्लेख है, वे एक उपनाम भी प्रदान करते हैं all


2
क्या अंडरस्कोर.जेएस इसके लिए भी एक कार्यान्वयन प्रदान करता है?
फेलिक्स क्लिंग

1
@FelixKling, हाँ यह करता है। मैंने अपने उत्तर में उसे जोड़ दिया है।
एस्क्रे

2
अभी (05/2013), अंडरस्कोर में सरणियों के लिए _.every()न तो एक _.all()विधि है और न ही - इसलिए स्टिक टू द Array.every()
pkyeck

3
यह काम करेगा, लेकिन यह उपयोग करने के लिए एक सामान्य कारण है every। तो पठनीयता के लिए बाहर देखो।
evanrmurphy

3
अंडरस्कोर डॉक्स के लिए _.each()विशेष रूप से इस तथ्य के बारे में एक नोट है कि आप लूप से बाहर नहीं निकल सकते हैं, और अनुशंसा करते हैं कि आप _.find()इसके बजाय उपयोग करते हैं। http://underscorejs.org/#each
Blatt

70

अपडेट करें:

_.find बेहतर होगा क्योंकि यह तत्व मिलने पर लूप से बाहर निकलता है:

var searchArr = [{id:1,text:"foo"},{id:2,text:"bar"}];
var count = 0;
var filteredEl = _.find(searchArr,function(arrEl){ 
              count = count +1;
              if(arrEl.id === 1 ){
                  return arrEl;
              }
            });

console.log(filteredEl);
//since we are searching the first element in the array, the count will be one
console.log(count);
//output: filteredEl : {id:1,text:"foo"} , count: 1

** पुराना **

यदि आप सशर्त रूप से एक लूप से बाहर निकलना चाहते हैं, तो _.each के बजाय _.filter एपीआई का उपयोग करें। यहाँ एक कोड स्निपेट है

var searchArr = [{id:1,text:"foo"},{id:2,text:"bar"}];
var filteredEl = _.filter(searchArr,function(arrEl){ 
                  if(arrEl.id === 1 ){
                      return arrEl;
                  }
                });
console.log(filteredEl);
//output: {id:1,text:"foo"}

1
यह लूप को तोड़ता नहीं है - यह सिर्फ सरणी को फ़िल्टर करता है। कल्पना कीजिए कि आपके पास सरणी में 2 नहीं बल्कि 20.000 आइटम हैं। आप लॉग केवल उदाहरण का उत्पादन करेंगे जिसे आपने पोस्ट किया था लेकिन लूप 20.000 बार चलेगा :(
pkyeck

@pkyeck आप सही हैं, _ हो सकता है कि _.filter __filter से बेहतर है क्योंकि यह हाथी के पाए जाने के बाद टूट जाता है, यहाँ है fiddle: jsfiddle.net/niki4810/9K3EV
निखिल

2
मुझे लगता है कि इस उत्तर को सही के रूप में चिह्नित किया जाना चाहिए। _.findक्या वास्तव में पूछा जाता है: कॉलबैक लौटने तक सूची पर पुनरावृति true
फेबियन क्वात्रावाक्स

इस उत्तर के लिए वोट किया गया क्योंकि स्वीकृत उत्तर (Array.every) वस्तुओं पर काम नहीं करेगा, लेकिन _.find () होगा।
मैट

और यह कि डॉक्स में क्या सिफारिश की गई है: यह नोट करना भी अच्छा है कि प्रत्येक लूप को तोड़ नहीं सकता है - इसके बजाय, तोड़ने के लिए _.find का उपयोग करें।
शहर्सोल

15

आप _.someइसके बजाय एक नज़र रख सकते हैं _.each_.someएक बार विधेय सत्य होने पर सूची को रोकना बंद कर देता है। परिणाम (ओं) को एक बाहरी चर में संग्रहित किया जा सकता है।

_.some([1, 2, 3], function(v) {
    if (v == 2) return true;
})

Http://underscorejs.org/#some देखें



3

हो सकता है कि आप अंडरस्कोर के किसी भी () या खोज () को चाहते हैं, जो एक शर्त पूरी होने पर प्रसंस्करण बंद कर देगा।



3

आप किसी forEachअंडरस्कोर में ब्रेक नहीं लगा सकते , क्योंकि यह एक्मास्क्रिप्ट 5 देशी व्यवहार का अनुकरण करता है।


2

मेरा मानना ​​है कि यदि आपका सरणी वास्तव में एक वस्तु थी तो आप एक खाली वस्तु का उपयोग करके वापस आ सकते हैं।

_.({1,2,3,4,5}).each(function(v){  
  if(v===3) return {}; 
});

यह केवल EcmaScript v <5 के साथ होता है, क्योंकि अंडरस्कोर की जांच करने के लिए कि क्या आप खाली ऑब्जेक्ट को दिए गए विकल्प में वापस लौट रहे हैं, केवल तभी किया जाता है जब मूल एक उपलब्ध न हो।
अल्फोंसो डे ला ओसा

2

यह नोट करना भी अच्छा है कि प्रत्येक लूप को तोड़ना नहीं है - को तोड़ने के लिए, इसके बजाय _.find का उपयोग करें।

http://underscorejs.org/#each


1

अपडेट करें:

आप वास्तव में एक त्रुटि को "फेंक" कर सकते हैं अंदर एक त्रुटि और इसे बाहर पकड़कर: कुछ इस तरह से:

try{
  _([1,2,3]).each(function(v){
    if (v==2) throw new Error('break');
  });
}catch(e){
  if(e.message === 'break'){
    //break successful
  }
}

यह स्पष्ट रूप से किसी भी अन्य अपवादों के बारे में कुछ निहितार्थ है कि आपका कोड लूप में ट्रिगर होता है, इसलिए सावधानी के साथ उपयोग करें!


प्यार कैसे मैं इस बात के लिए इतने सारे नीचे वोट मिलता है, और इस आदमी को उसके लिए अप की एक पूरी लोड हो जाता है stackoverflow.com/a/2641374/674720
bm_i

1
मुझे पार्टी के लिए देर हो रही है लेकिन ध्यान दें कि उस आदमी ने न केवल वही कहा जो आपने सुझाया था, बल्कि दो और विकल्पों (और अधिक उपयुक्त) की पेशकश की। केवल "हैक" की पेशकश की अगर उपयोगकर्ता हर तरह से इसे चाहता है। इसके बजाय आपने केवल बदसूरत हैक की पेशकश की।
Areks

0

मेरे मामले में काम किया

var arr2 = _.filter(arr, function(item){
    if ( item == 3 ) return item;
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.