2017-08-29 16 views
15

मैं ऐसे फ़ंक्शन पर मानों को मैप करने की कोशिश कर रहा हूं जो गुणा करने के लिए दो संख्या स्वीकार करेंगे लेकिन ऐसा करने में परेशानी हो रही है (यदि यह समझ में नहीं आता है, तो नीचे दिए गए उदाहरणों पर नज़र डालें)।पैरामीटर को array.map() में कैसे पास किया जाए?

मेरे पास संख्याओं की एक सरणी है और मैं इस सरणी के मानों को डबल/ट्रिपल/चौगुनी करना चाहता हूं। मैंने ऐसे फ़ंक्शन बनाए हैं जो ऐसा करेंगे, और double() और triple() को map() में खिला रहे हैं।

var arr = [1, 2, 3, 4, 5]; 

function double(num) { 
    return num * 2; 
} 

function triple(num) { 
    return num * 3; 
} 

console.log(arr.map(double)); 
console.log(arr.map(triple)); 

यह समाधान स्केलेबल नहीं है क्योंकि मैं मानों को 5 या 10 से गुणा करना चाहता हूं? मुझे एक और अमूर्त फ़ंक्शन की आवश्यकता है जो गुणा करने के लिए पैरामीटर लेगा। मैं इस बारे में उलझन में हूं कि यह कैसे करें। मेरे प्रयास अब तक है:

var arr = [1, 2, 3, 4, 5]; 

function multiply(num, multiplyBy) { 
    return num * multiplyBy; 
} 

console.log(arr.map(multiplyBy(4)); // Uncaught TypeError: NaN is not a function 

मैं multiply()multiplyBy पैरामीटर कैसे पारित होगा?

उत्तर

16

आप कारखाने नामक कुछ कर सकते हैं। प्रभावी रूप से, आप एक ऐसा फ़ंक्शन बनाते हैं जो आपकी आवश्यकताओं के अनुरूप एक और फ़ंक्शन लौटाएगा। इस मामले में, एक अज्ञात एक।

var arr = [1, 2, 3, 4, 5]; 

function multiplyBy(scale) { 
    return function(num){ 
     return num * scale; 
    } 
} 

console.log(arr.map(multiplyBy(4))); 

यह काम करता है क्योंकि लौटाए गए अज्ञात फ़ंक्शन का दायरा कारखाने के भीतर है। इसलिए, जब भी हम एक नया कार्य तैयार करते हैं, तो यह scale के मूल्य को बनाए रखेगा जो इसके उत्पादन के लिए दिया गया था।

संपादित करें: @ बर्गि के उत्तर का अंतिम भाग मेरा जैसा ही है। अवधारणा को स्पष्ट रूप से करीकरण कहा जाता है। धन्यवाद @ बर्गि! बर्गी ने नोट किया कि कारखाने के पैटर्न को ऑब्जेक्ट्स के उत्पादन पर अधिक बार लागू किया जाता है, लेकिन यह एकमात्र चीज थी जिसे मैं उस समय सोच सकता था, और जावास्क्रिप्ट सॉर्ट ऑब्जेक्ट्स जैसे कार्यों का व्यवहार करता था। इस विशिष्ट मामले में, वे प्रभावी रूप से समान हैं।

+3

मैं केवल "फ़ैक्टरी" शब्द का उपयोग उन कार्यों के लिए करता हूं जो ऑब्जेक्ट लौटाते हैं। – Bergi

+0

मैंने अपना उत्तर अधिक पठनीय बना दिया, मैंने केवल अजीब इंडेंटेशन का उपयोग केवल ईएस 6 तीर फ़ंक्शन को एक-लाइनर में बदलने के लिए किया। – Bergi

+1

यह उत्तर '.bind' का उपयोग करने से समझना आसान है – Denny

10

आप बाध्य तर्कों के साथ एक नया फ़ंक्शन बनाने के लिए Function.prototype.bind का उपयोग कर सकते हैं। उदाहरण

लिए

var arr = [1, 2, 3, 4, 5]; 
 

 
function multiplyBy(multiplyBy, num) { 
 
    // note the "num" argument must come last if it is to represent the argument from "map" 
 
    return num * multiplyBy; 
 
} 
 

 
console.log(arr.map(multiplyBy.bind(null, 4))); // null is for the "this" argument

14

आप partial application के लिए देख रहे हैं। यह उदाहरण के लिए bind के साथ किया जा सकता है (या कि in Underscore की तरह, कार्यात्मक पुस्तकालयों के साथ आए सहायक कई कार्य करने की):

arr.map(multiplyBy.bind(null, 4)) 

लेकिन एक साधारण तीर समारोह आसान होगा:

arr.map(x => multiplyBy(4, x)) 

लेकिन आप अगर आप अपने multiplyBy समारोह curry भी मुक्त करने के लिए आंशिक आवेदन प्राप्त कर सकते हैं, गुणक ले रहे हैं और एक नया कार्य लौटने:

function multiplyBy(multiplier) { 
    return function(num) { 
    return num * multiplier; 
    }; 
} 
// ES6 arrow functions: 
const multiplyBy = multiplier => num => num * multiplier; 

arr.map(multiplyBy(4)); 
संबंधित मुद्दे