2012-08-03 6 views
7

मैं स्कैला के लिए नया ब्रांड हूं, जिसमें हास्केल के माध्यम से कार्यात्मक प्रोग्रामिंग के साथ बहुत सीमित अनुभव था।सभी जोड़े की एक सूची तैयार करना

मैं एक इनपुट सूची से बने सभी संभावित जोड़े की एक सूची लिखने का प्रयास करना चाहता हूं। उदाहरण:

val nums = List[Int](1, 2, 3, 4, 5) // Create an input list 
val pairs = composePairs(nums)  // Function I'd like to create 

// pairs == List[Int, Int]((1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1) ... etc) 

मैं पूरी सूची के साथ प्रत्येक तत्व पर zip उपयोग करने की कोशिश, उम्मीद है कि यह पूरी भर में एक आइटम नकल होगा। यह काम नहीं किया (केवल पहली संभव जोड़ी से मेल खाता है)। मुझे यकीन नहीं है कि तत्व को दोहराना कैसे है (हास्केल cycle और take के साथ करता है), और मुझे स्कैला पर प्रलेखन के बाद परेशानी हुई है।

इससे मुझे यह सोचने लगता है कि संभवतः परिणाम प्राप्त करने के लिए शायद एक संक्षिप्त, कार्यात्मक तरीका है। क्या किसी के पास अच्छा समाधान है?

+3

यह आपरेशन, जो आप चाहते के लिए शब्दावली जानने के लिए बहुत उपयोगी है। इस मामले में, आप सूची के उत्पाद को अपने साथ ढूंढने की कोशिश कर रहे हैं। इसे देखें: http://stackoverflow.com/questions/8217764/cartesian-product-of-two-lists – Marcin

+0

@ मार्सिन धन्यवाद। मुझे किसी भी प्रकार की कार्यात्मक प्रोग्रामिंग सीखने की दिशा में सबसे बड़ी चुनौतीपूर्ण ब्लॉकों में से एक मिला है जो नई शब्दावली उठा रहा है। – KChaloux

+0

क्रॉस उत्पाद? कार्टेशियन उत्पाद के समान ही? यदि स्पार्क यहां प्रासंगिक है, तो [यह उत्तर] (http://stackoverflow.com/a/26565173/1175496) भी प्रासंगिक है –

उत्तर

20

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

val pairs = for(x <- nums; y <- nums) yield (x, y) 
+0

शानदार काम करता है। मुझे पूरा यकीन नहीं है * क्यों * यह काम करता है। '(X <- nums; y <- nums)' के लिए '(x <- nums) के लिए' y <- nums) 'के संक्षिप्त तरीके की तरह है? – KChaloux

+6

@KChaloux: यह 'nums.flatMap (x => nums.map ((x, _)) के लिए वाक्य रचनात्मक चीनी है, '', जो अनिवार्य रूप से' nums.map (x => nums.map ((x, _) है)) .flatten', अगर यह मदद करता है। –

+0

@dbyrne यह निश्चित रूप से अंतर्दृष्टि है जिसका मैं उपयोग कर सकता हूं। – KChaloux

1

यहाँ नक्शा और समतल

val pairs = nums.flatMap(x => nums.map(y => (x,y)))

List[(Int, Int)] = List((1,1), (1,2), (1,3), (1,4), (1,5), (2,1), (2,2), (2,3), (2,4), (2,5), (3,1), (3,2), (3,3), (3,4), (3,5), (4,1), (4,2), (4,3), (4,4), (4,5), (5,1), (5,2) (5,3), (5,4), (5,5))

यह यदि आप चाहें तो आसानी से एक composePairs समारोह में लपेटा जा सकता है का उपयोग करते हुए एक और संस्करण है:

def composePairs(nums: Seq[Int]) = 
    nums.flatMap(x => nums.map(y => (x,y))) 
+2

बेहतर 'मानचित्र के बजाय' flatMap (...) 'का उपयोग करें (...)। Flatten'। –

2

आप में से जो लोग डुप्लिकेट नहीं करना चाहते हैं के लिए:

val uniquePairs = for { 
     (x, idxX) <- nums.zipWithIndex 
     (y, idxY) <- nums.zipWithIndex 
     if idxX < idxY 
    } yield (x, y) 

val nums = List(1,2,3,4,5) 
uniquePairs: List[(Int, Int)] = List((1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)) 
+0

आप '<=' चाहते हैं। आपके आउटपुट की अनुपलब्ध (उदा।) '(1,1)' –

+0

कुछ मामलों में डुप्लिकेट के रूप में '(x, x) 'देख सकता है। '<=' जोड़ना या '>', '> =' को बदलना स्पष्ट होना चाहिए। – keos