2011-10-13 11 views
82

मैं एक स्ट्रिंग के साथ एक ऐरे में प्रत्येक स्ट्रिंग की तुलना करना चाहता हूं। मेरे वर्तमान कार्यान्वयन है:मैं जावास्क्रिप्ट .filter() विधि में कॉलबैक फ़ंक्शन में अतिरिक्त पैरामीटर कैसे पास करूं?

function startsWith(element) { 
    return element.indexOf(wordToCompare) === 0; 
} 
addressBook.filter(startsWith); 

यह सरल समारोह काम करता है, लेकिन केवल क्योंकि अभी wordToCompare एक वैश्विक चर के रूप में स्थापित किया जा रहा है, लेकिन निश्चित रूप से मैं इस से बचने और एक पैरामीटर के रूप में यह पारित करने के लिए चाहते हैं। मेरी समस्या यह है कि मुझे यकीन नहीं है कि प्रारंभ करने के साथ कैसे शुरू करें() इसलिए यह एक अतिरिक्त पैरामीटर स्वीकार करता है, क्योंकि मैं वास्तव में समझ नहीं पा रहा हूं कि डिफ़ॉल्ट पैरामीटर कैसे पारित होते हैं। मैंने उन सभी अलग-अलग तरीकों की कोशिश की है जिनके बारे में मैं सोच सकता हूं और उनमें से कोई भी काम नहीं करता है।

आप भी समझा सकता है तो कैसे कॉलबैक कार्यों 'में बनाया गया' काम (क्षमा करें, मैं करने के लिए इन एक बेहतर शब्द की नहीं जानता) के लिए पारित पैरामीटर बहुत अच्छा होगा

उत्तर

119

startsWith बनाओ शब्द स्वीकार के खिलाफ तुलना करने के लिए और एक समारोह जो तब फिल्टर/कॉलबैक समारोह के रूप में इस्तेमाल किया जाएगा वापसी:

function startsWith(wordToCompare) { 
    return function(element) { 
     return element.indexOf(wordToCompare) === 0; 
    } 
} 

addressBook.filter(startsWith(wordToCompare)); 

एक अन्य विकल्प भाई में Function.prototype.bind[MDN] (केवल उपलब्ध उपयोग करने के लिए किया जाएगा wser समर्थन ECMAScript 5, पुराने ब्राउज़र के लिए एक परत के लिए एक लिंक पर जाएं) और "ठीक" पहला तर्क:

function startsWith(wordToCompare, element) { 
    return element.indexOf(wordToCompare) === 0; 
} 

addressBook.filter(startsWith.bind(this, wordToCompare)); 

मैं सच में समझ में न कैसे डिफ़ॉल्ट पैरामीटर लेता है पारित कर रहे हैं

इसके बारे में कुछ खास नहीं है। किसी बिंदु पर, filter बस कॉलबैक को कॉल करता है और सरणी के वर्तमान तत्व को पास करता है। तो यह एक फ़ंक्शन है जो किसी अन्य फ़ंक्शन को कॉल करता है, इस मामले में आप जिस कॉलबैक को तर्क के रूप में पास करते हैं।

यहाँ एक समान कार्य का एक उदाहरण है:

function filter(array, callback) { 
    var result = []; 
    for(var i = 0, l = array.length; i < l; i++) { 
     if(callback(array[i])) { // here callback is called with the current element 
      result.push(array[i]); 
     } 
    } 
    return result; 
} 
+1

ठीक है अब मैं समझता हूँ। मैं सीधे कॉलबैक फ़ंक्शन पर पैरामीटर को पारित करने का प्रयास कर रहा था ... मुझे वास्तव में मेरी जावास्क्रिप्ट पर काम करने की ज़रूरत है। धन्यवाद फेलिक्स, आपका उत्तर बहुत उपयोगी है –

+0

अतिरिक्त तर्क पारित करने के बारे में क्या? मैंने तर्कों की एक सरणी पारित करने का प्रयास किया लेकिन ऐसा लगता है कि – geotheory

+0

@ गोथोरी: उनके बारे में क्या? आप किसी भी अन्य फ़ंक्शन की तरह कई तर्क पारित करते हैं। –

10
function startsWith(element, wordToCompare) { 
    return element.indexOf(wordToCompare) === 0; 
} 

// ... 
var word = "SOMETHING"; 

addressBook.filter(function(element){ 
    return startsWith(element, word); 
}); 
75

फिल्टर का दूसरा पैरामीटर इस सेट हो जाएगा कॉलबैक के अंदर।

function startsWith(element) { 
    return element.indexOf(this) === 0; 
} 
addressBook.filter(startsWith, wordToCompare); 
+19

यह उत्तर स्वीकार किया जाना चाहिए :) – DrLightman

+3

मुझे पता चला कि यह सबसे अच्छा जवाब है। –

+0

तो अब नया सरणी wordToCompare ऑब्जेक्ट को सौंपा जाएगा, है ना? शब्दको कॉम्पैयर ऑब्जेक्ट का उपयोग करके बाद में नई सरणी का उपयोग कैसे कर सकते हैं? –

2

आप एक फिल्टर के अंदर तीर समारोह का उपयोग कर सकते, इस तरह::

arr.filter(callback[, thisArg]) 

तो आप की तरह कुछ कर सकते हैं

result = addressBook.filter(element => element.indexOf(wordToCompare) === 0); 

Arrow functions on MDN

एक तीर फ़ंक्शन अभिव्यक्ति की तुलना में फ़ंक्शन अभिव्यक्ति में एक छोटा वाक्यविन्यास होता है आयनों और इस मूल्य को स्पष्ट रूप से बांधता है (यह स्वयं, तर्क, सुपर, या new.target बांध नहीं है)। तीर कार्य हमेशा अज्ञात होते हैं। ये फ़ंक्शन एक्सप्रेशन गैर-विधि कार्यों के लिए सबसे उपयुक्त हैं और इन्हें कन्स्ट्रक्टर के रूप में उपयोग नहीं किया जा सकता है।

+0

नोट: आईई पर समर्थित नहीं है –

0

oddRaven जवाब और https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

मैं इसे 2 अलग तरीके से किया था पर आधारित है। 1) फ़ंक्शन तरीके का उपयोग करना। 2) इनलाइन तरीके का उपयोग कर।

//Here is sample codes : 
 

 
var templateList = [ 
 
{ name: "name1", index: 1, dimension: 1 } , 
 
{ name: "name2", index: 2, dimension: 1 } , 
 
{ name: "name3", index: 3, dimension: 2 } ]; 
 

 

 
//Method 1) using function : 
 

 
function getDimension1(obj) { 
 
       if (obj.dimension === 1) // This is hardcoded . 
 
        return true; 
 
       else return false; 
 
      } 
 

 
var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects. 
 
console.log(tl) ; 
 

 
//Method 2) using inline way 
 
var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2 ); 
 
// it will return 1st and 3rd objects 
 
console.log(tl3) ;

3

तीर कार्यों का उपयोग कर एक ES6 विकल्प की तलाश में उन लोगों के लिए, आप निम्न कर सकते हैं।

let startsWith = wordToCompare => (element, index, array) => { 
    return element.indexOf(wordToCompare) === 0; 
} 

// where word would be your argument 
let result = addressBook.filter(startsWith(word)); 
सोच क्यों उनके वसा तीर समारोह [, thisArg] अनदेखी कर रहा है किसी को भी, उदा लिए
1

क्यों

["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG") रिटर्न []

यह क्योंकि this उन तीर कार्यों के अंदर बाध्य कर रहे हैं जब समारोह बनाई गई है और व्यापक को शामिल दायरे में this के मान पर सेट कर रहे हैं, तो thisArg तर्क को नजरअंदाज कर दिया जाता है। मैं एक माता पिता के दायरे में एक नया वेरिएबल की घोषणा के द्वारा बहुत आसानी से इस के आसपास मिल गया: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

0

एक आसान तरीका फिल्टर समारोह का उपयोग करने के है:

let bestPet = "DOG"; ["DOG", "CAT", "DOG"].filter(animal => animal === bestPet); => ["DOG", "DOG"]

यहां कुछ और पढ़ने के लिए एक लिंक है , सभी पैरामों तक पहुंचें, और इसे जटिल नहीं करें।

कॉलबैक के जब तक यह एआरआर किसी अन्य स्कोप फ़िल्टर पर सेट नहीं होता है, तो इसका अपना दायरा नहीं बनता है, और हम वर्तमान दायरे में पैराम तक पहुंच सकते हैं। यदि आवश्यक हो तो अन्य मूल्यों तक पहुंचने के लिए हम एक अलग-अलग दायरे को परिभाषित करने के लिए 'यह' सेट कर सकते हैं, लेकिन डिफ़ॉल्ट रूप से यह उस दायरे पर सेट होता है जिसे इसे कहा जाता है। आप देख सकते हैं कोणीय स्कॉप्स in this stack के लिए उपयोग किया जा रहा है।

इंडेक्स का उपयोग करना फ़िल्टर के उद्देश्य को हरा रहा है, और अधिक ओवरहेड जोड़ रहा है। फ़िल्टर पहले से ही सरणी के माध्यम से जा रहा है, तो हमें फिर से इसके माध्यम से फिर से प्रयास करने की आवश्यकता क्यों है? हम इसे एक साधारण pure function बना सकते हैं।

यहां कक्षा विधि प्रतिक्रिया जहां राज्य एक सरणी कहा जाता आइटम है के भीतर एक उपयोग हालत में है, और फिल्टर का उपयोग करके हम मौजूदा राज्य की जाँच कर सकते हैं:

checkList = (item) => { // we can access this param and globals within filter 
    var result = this.state.filter(value => value === item); // returns array of matching items 

    result.length ? return `${item} exists` : this.setState({ 
    items: items.push(item) // bad practice, but to keep it light 
    }); 
} 
संबंधित मुद्दे