2012-08-02 13 views
10

क्या अनावश्यक तर्कों को अनदेखा करने के लिए कोई आसान तरीका है?अनावश्यक तर्कों को अनदेखा कैसे करें?

उदाहरण के लिए: (#(+ %1 %2) 1 2) रिटर्न 3

मैं इस कोड

(#(+ %1 %2) 1 2 3) 
रिटर्न 3 भी करने के लिए

मजबूर करने के लिए करना चाहते हैं। लेकिन यह रिटर्न

java.lang.IllegalArgumentException: आर्ग की गलत संख्या (3) के लिए पारित ।

#(+ %1 %2) कैसे बदलें?

मुझे आशा है कि #(+ (nth %& 0) (nth %& 1)) से कुछ और शानदार तरीका है।

उत्तर

18

यहाँ मैं के साथ जाना होगा है:

=> ((fn [a b & _] (+ a b)) 1 2 3) 
=> 3 

इस को उस अज्ञात फ़ंक्शन तर्क के किसी भी संख्या लेता है बनाता है, लेकिन सिर्फ पहले दो कहते हैं। _ प्रतीक कुछ खास नहीं कर रहा है, यह सिर्फ मूर्खतापूर्ण है "मुझे इस बात की परवाह नहीं है, लेकिन मुझे इसे किसी भी तरह से बांधने की ज़रूरत है"। आपको लगता है कि आप इस एक बहुत कुछ कर जा करने के लिए जा रहे हैं, तो आप शायद यह निर्धारित करना चाहते हैं:

(defn add-first-two 
    [a b & _] 
    (+ a b)) 

आप #() वाक्य विन्यास में वास्तव में कर रहे हैं, तो आप इसके लिए परिभाषा में कहीं %& शामिल करना होगा "एहसास" करने के लिए कि इसे किसी भी तर्क लेना चाहिए। इसका मतलब यह नहीं है कि आपको दिखाए जाने के बाद इसे इंडेक्स करना होगा, इसे कहीं उपस्थित होना होगा।यहाँ एक उदाहरण है:

=> (#(do %& (+ %1 %2)) 1 2 3) 
=> 3 

दूसरी ओर, इस समाधान %&, जहां आप किसी की जरूरत नहीं है के प्रसंस्करण के कुछ प्रकार शामिल है, और धीमी गति से चीजों को नीचे से थोड़ा (मैं नहीं इस बारे में यकीन है कि हो सकता है , शायद कोई और मुझे इस पर प्रतिक्रिया दे सकता है)। एक मजेदार समाधान %& को (comment ...) ब्लॉक के अंदर चिपकाना होगा, जो nil का मूल्यांकन करेगा।

=> (#(do (comment %&) (+ %1 %2)) 1 2 3) 
=> 3 

एक और भी अधिक विदेशी समाधान #_..., जो सिवाय इसके कि पाठक वास्तव में, मूल्यांकन से निकालता है जैसे कि आप बस वहाँ कुछ भी नहीं लिखा हो (comment...) की तरह एक बहुत कुछ है उपयोग करने के लिए किया जाएगा। इस तरह, शायद हम कोड को छोटा करने के लिए (+ ...) के शरीर के अंदर चिपक सकते हैं।

=> (#(+ %1 %2 #_%&) 1 2 3) 
=> 3 

आपको क्या पता है, यह काम करता है। मैं वास्तव में पहले कभी यह कोशिश नहीं करता था, और मैं इसे देखने के लिए आश्चर्यचकित हूं। जाहिर है, #_... अनुभाग से पहले कुछ प्रसंस्करण हटा दिया गया है। अजीब।

आप इन अजीब टिप्पणी समाधान से किसी को पसंद नहीं करते हैं, और do यह आप के लिए नहीं कर रहा है, तो आप हमेशा यह एक (if nil ...) ब्लॉक के अंदर डाल सकता है:

=> (#(if nil %& (+ %1 %2)) 1 2 3) 
=> 3 

खैर सब के बाद, कि , मुझे अभी भी पहला समाधान सबसे अच्छा लगता है ((fn ...) का उपयोग करके), लेकिन इनमें से कुछ निश्चित रूप से कम हैं।

5

इस तर्क के किसी भी संख्या के लिए काम करता है, और पठनीय है:

(fn [& args] (apply + (take 2 args))) 

आप कर सकते हैं:

(fn [& args] (apply + args)) 

आप केवल पहले 2 तर्कों का उपयोग करने के (एलेक्स 'टिप्पणी के अनुसार) चाहते हैं इस तरह एक प्रतीक को

((fn [& args] (apply + (take 2 args))) 1 2) 
; => 3 

या बाँध समारोह: सीधे इसका इस्तेमाल

0,123,
(let [f (fn [& args] (apply + (take 2 args)))] 
    (f 1 2)) 
; => 3 

या एक वर बनाएँ:

(def f (fn [& args] (apply + (take 2 args)))) 

या एक समारोह:

(defn f [& args] (apply + (take 2 args))) 

सबसे अच्छी परिभाषा आपके उपयोग के मामले पर निर्भर करता है।

+2

यह सभी तर्कों को संक्षेप में जोड़ रहा है। ओपी ने पहले दो की राशि के लिए पूछा, किसी भी अतिरिक्त अनदेखा के साथ, तो आपको कहना होगा (एफएन [और तर्क] (लागू करें + (2 तर्क लें)) – Alex

+1

यह एक अच्छा बिंदु है - मेरा जवाब अपडेट किया गया। – Gert

1
user> (#(do %& (+ % %2)) 1 2) 
3 
user> (#(do %& (+ % %2)) 1 2 3) 
3 

यह बहुत ही सुरुचिपूर्ण नहीं है, लेकिन मुझे लगता है कि यह स्वीकार्य है।

4

इस बारे में कैसे?

(#(apply + (take 2 %&)) 1 2 3 4 5) 
;; => 3 
संबंधित मुद्दे