2012-02-02 9 views
9

क्लोजर में, दो seqs पर समवर्ती रूप से पुनरावृत्त करने और दो चल रहे तत्वों पर फ़ंक्शन को कॉल करने का सबसे अच्छा तरीका क्या है? उदाहरण के लिए:क्लोजर कैसे दो seqs के तत्वों पर एक समारोह निष्पादित करने के लिए?

(def a (range 3)) 
(def b (range 100 103)) 
(defn my-func [] ...) ;some custom code 

कोड इस तरह मेरी-समारोह को अंजाम चाहिए 3 बार,:

(my-func 0 100) 
(my-func 1 101) 
(my-func 2 102) 

मैं कैसे प्राप्त कर सकते हैं कि किसी भी कार्य या मैक्रो को परिभाषित करने के बिना?

+1

(रेंज 100 102) में केवल दो तत्व हैं - शायद आपका मतलब है (सीमा 100 103)? – mikera

+0

@ मिकरा: धन्यवाद। प्रश्न – viebel

उत्तर

15

map वही है जो आपको चाहिए, यह एक समारोह और किसी भी संख्या में seqs लेता है और जैसा कि आप चाहें उन्हें कॉल करते हैं।

(def a (range 3)) 
(def b (range 100 103)) 
user=> a 
(0 1 2) 
user=> b 
(100 101 102) 

user=> (defn my-func [a b] (str a ":" b)) 
#'user/my-func 

user=> (my-func 1 2) 
"1:2" 

user=> (map my-func a b) 
("0:100" "1:101" "2:102") 

और क्योंकि map आलसी है अगर आप वास्तव में समारोह अब चलाना चाहते हैं:

(doall (map my-func a b)) 
+0

अद्यतन किया यह काम नहीं करता है। यह आउटपुट: (0: 100 1: 101 शून्य शून्य) – viebel

+0

@ विएबेल: क्या आप आरईपीएल पर चल रहे हैं और 'println' का उपयोग कर रहे हैं? यदि हां, तो आपके परिणाम उलझन में हैं। मान लीजिए कि आप भाग गए थे (नक्शा # (println% 1 ":"% 2) ab) ', क्या हुआ है कि आरईपीएल मुद्रित' (', फिर' println' '0: 100' और' 1: 101' मुद्रित है, फिर आरईपीएल ने मानचित्र के परिणामों को प्रिंट करना समाप्त कर दिया, जो 'शून्य शून्य) है। – mange

+0

नील नील इसे संपादित करने से पहले प्रिंसल की वापसी है –

3

तुम भी जहां पहला तत्व एक है

(doseq [[x y] (map list my-list1 my-list2)] 
    (println x y)) 

(map list list-2 list-2) एक सूची बनाता है की कोशिश कर सकते इनपुट सूचियों के पहले तत्वों की सूची, दूसरा तत्व दूसरे तत्वों की एक सूची है, ...

हम फिर मूल सूचियों के तत्व निकालने के लिए क्लोजर के विनाश का उपयोग करके सूची में फिर से प्रयास करते हैं।

सामान्य रूप से, आप map चाहते हैं यदि आप उस फ़ंक्शन के रिटर्न वैल्यू का उपयोग करना चाहते हैं जिसे आप आवेदन कर रहे हैं। यदि आप अपने दुष्प्रभावों के लिए केवल एक फ़ंक्शन निष्पादित कर रहे हैं, तो मैं आमतौर पर doseq का उपयोग करता हूं। यह मामला इस तथ्य से जटिल है कि map समानांतर में काम करता है, जबकि doseq सूचियों के Cartesian Product से अधिक होता है, इसलिए आपको इच्छित व्यवहार प्राप्त करने के लिए map और doseq दोनों की आवश्यकता होती है।

+0

क्या कोई डोसक-जैसा फ़ंक्शन है जो समानांतर में चलता है और कार्टेशियन उत्पाद पर नहीं। यदि नहीं, इसके पीछे तर्क क्या है? – viebel

+0

जहाँ तक मुझे पता है, ऐसा कोई कार्य नहीं है। आदर्श रूप से doseq/के लिए (वे एक ही वाक्यविन्यास साझा करते हैं) कुछ ऐसा करने की अनुमति देंगे: और दो समानांतरों को समानांतर में दोहराने की अनुमति देने का विकल्प। दुर्भाग्य से, ऐसा कोई विकल्प मौजूद नहीं है। – Retief

0

(doseq ... (map समाधान के लिए एक वैकल्पिक, अगर आप जोड़ो में के बजाय यात्रा कार्तीय उत्पाद चाहते हैं, तो आप भी partitioninterleave इस तरह के साथ गठबंधन कर सकते हैं:

> (def a (range 0 3)) 
> (def b (range 100 103)) 
> (interleave a b) 
(0 100 1 101 2 102) 
> (partition 2 (interleave a b)) 
((0 100) (1 101) (2 102)) 

partition कॉल जोड़े की एक (आलसी) seq प्रदान करता है।

संबंधित मुद्दे