2009-10-23 22 views
10

वैकल्पिक नामित तर्कों के साथ फ़ंक्शन को परिभाषित करने का सबसे अच्छा/कैननिकल तरीका क्या है? इसे ठोस बनाने के लिए, चलिए foo नामित तर्क a, b, और c, जो डिफ़ॉल्ट रूप से 1, 2, और 3 के साथ एक फ़ंक्शन बनाते हैं। तुलना के लिए, यहाँ स्थितीय तर्क के साथ foo का एक संस्करण है:वैकल्पिक नामित गणित गणित

foo[]     --> bar[1,2,3] 
foo[b->7]    --> bar[1,7,3] 
foo[a->6, b->7, c->8] --> bar[6,7,8] 

यह निश्चित रूप से करना चाहिए भी है करने के लिए आसान हो सकता है:

foo[a_:1, b_:2, c_:3] := bar[a,b,c] 

यहाँ नमूना इनपुट और foo के नाम पर रखा गया-तर्क संस्करण के लिए उत्पादन होता है नामित तर्क से पहले स्थितित्मक तर्क।

+0

यह भी देखें: http: // stackoverflow।कॉम/प्रश्न/4682742/वैकल्पिक-नाम-तर्क-बिना-रैपिंग-इन-ऑल-इन-विकल्पव्यू – dreeves

उत्तर

10

मैं मेथेमेटिका दस्तावेज में यह करने के लिए मानक रास्ता मिल गया थोड़ा बोझिल किसी कारण से आप बस ov = OptionValue की तरह एक वैश्विक संक्षिप्त नाम नहीं कर सकते हैं, लेकिन आप यह कर सकते हैं:

foo[OptionsPattern[]] := Module[{ov}, 
    ov[x___] := OptionValue[x]; 
    bar[[email protected], [email protected], [email protected]]] 

या इस:

With[{ov = OptionValue}, 
    foo[OptionsPattern[]] := bar[[email protected], [email protected], [email protected]] 
] 

या इस:

$PreRead = ReplaceAll[#, "ov" -> "OptionValue"] &; 

foo[OptionsPattern[]] := bar[[email protected], [email protected], [email protected]] 
+0

विकल्पवैल्यू के बोझिल टाइपिंग के बारे में: इस मामले में आप '[32]: = OptionValue/@ bar [a, बी, सी] आउट [32] = बार [OptionValue [ए], OptionValue [बी], OptionValue [सी]] ' –

+0

@dreeves 'कोड' के बजाय' साथ 'का उपयोग करके अंतिम कोड ब्लॉक का एक संक्षिप्त संक्षिप्त रूप है। Module'। क्या मैं इसे जोड़ने के लिए अपना जवाब संपादित कर सकता हूं? –

+0

@Sjoerd मजाकिया, जब मैंने इस पृष्ठ को लोड किया था तब आपकी टिप्पणी नहीं थी। मुझे लगता है कि आप इन पुरानी पोस्ट भी पढ़ रहे हैं। –

2

मैं मिश्रण में यह संभव समाधान फेंक देंगे:

foo[opts___Rule] := Module[{f}, 
    [email protected] = 1; (* defaults... *) 
    [email protected] = 2; 
    [email protected] = 3; 
    each[a_->v_, {opts}, [email protected] = v]; 

    Return[bar[[email protected], [email protected], [email protected]]] 
] 

मैं इसे अपनी terseness के लिए पसंद है, लेकिन मैं इसे मानक तरीका नहीं लगता। इस तरह से करने के साथ कोई गठिया?

पुनश्च, यह नीचे दिए सुविधाजनक उपयोगिता फ़ंक्शन का उपयोग करता: http://reference.wolfram.com/mathematica/tutorial/SettingUpFunctionsWithOptionalArguments.html

Options[foo] = {a->1, b->2, c->3}; (* defaults *) 
foo[OptionsPattern[]] := bar[[email protected], [email protected], [email protected]] 

टंकण "OptionValue" हर बार एक है:

SetAttributes[each, HoldAll];    (* each[pattern, list, body]  *) 
each[pat_, lst_, bod_] :=     (* converts pattern to body for *) 
    Scan[Replace[#, pat:>bod]&, [email protected]] (* each element of list.  *) 
4

हाँ, OptionValue थोड़ा मुश्किल हो सकता है क्योंकि जादू के टुकड़े पर निर्भर करता है ताकि

OptionValue[name]OptionValue[f,name] के समतुल्य है, जहां f परिवर्तन नियम के बाईं ओर स्थित है जिसमें OptionValue[name] प्रकट होता है।

एक स्पष्ट Automatic में फेंकने आमतौर पर है चाल, आपके मामले में मैं कहूंगा कि इतना है कि समाधान है:

Options[foo] = {a -> 1, b -> 2, c -> 3}; 
foo[OptionsPattern[]] := 
    bar @@ (OptionValue[Automatic, #] &) /@ First /@ Options[foo] 

वैसे, विकल्प opts:___?OptionQ का मिलान करके किया जाना करते थे, और फिर विकल्प मानों को मैन्युअल रूप से {a,b,c}/.Flatten[{opts}] के रूप में ढूंढें। पैटर्न चेक OptionQ अभी भी आसपास है (हालांकि दस्तावेज नहीं है), लेकिन OptionValue दृष्टिकोण का लाभ यह है कि आपको गैर-मौजूदा विकल्पों (उदा। foo[d->3]) के लिए चेतावनियां मिलती हैं। यह आपकी दूसरी प्रतिक्रिया के मामले भी होगा, लेकिन आपके द्वारा स्वीकार किए गए किसी भी व्यक्ति के लिए नहीं।