2011-09-28 19 views
17

कहें कि मेरे पास एक ऐसा फ़ंक्शन है जो जांचता है कि कुछ ऑपरेशन ए के उदाहरण पर लागू होता है और यदि ऐसा है, तो बी या कोई नहीं का उदाहरण देता है:स्कैला: विकल्पों का संग्रह फ़िल्टर करना

 def checker[A,B](a: A) : Option[B] = ... 

अब मैं एक नया संग्रह बनाना चाहता हूं जिसमें सभी मान्य हैं बी के उदाहरण, कोई भी मूल्य छोड़ना। निम्न कोड नौकरी करने लगता है, लेकिन निश्चित रूप से एक बेहतर तरीका है:

 val as = List[A](a1, a2, a3, ...) 
    val bs = 
    as 
    .map((a) => checker(a)) // List[A] => List[Option[B]] 
    .filter(_.isDefined)  // List[Option[B]] => List[Option[B]] 
    .map(_.get)    // List[Option[B]] => List[B] 

धन्यवाद!

+28

फ्लैटमैप जो –

+0

@oxbow_lakes मुझे लगता है कि सही उद्धरण है: _ "यह क्या है? एमेच्योर घंटा? फ्लैटमैप जो बकवास करता है!" _ –

+0

क्या यह उद्धरण ट्विटर पर उत्पन्न हुआ था? – huynhjl

उत्तर

25

यह करना चाहिए:

val bs = as.flatMap(checker) 
+0

विभिन्न कारणों से मेरे लिए काम नहीं करता है: 1. अनुमान टाइप करें, 2. सूची # flatMap एक GenTraversableOnce की अपेक्षा करता है। सही है .flatMap {a => चेकर [ए, बी] (ए)} – IttayD

+0

मैंने इसे 'Int' से' विकल्प [स्ट्रिंग] 'के फ़ंक्शन के साथ परीक्षण किया। सबसे खराब मामला, आपको इसमें कुछ स्पष्ट प्रकार जोड़ना होगा। –

+2

2.9.1 –

10

जवाब ऊपर सही है, लेकिन अगर आप checker पुनर्लेखन कर सकते हैं, मैं तुम्हें PartialFunction और collect का उपयोग सुझाव देते हैं। PartialFunction ग्रुप ए के एक समारोह है => बी कि आवश्यक नहीं है ए यहाँ के सभी मानों के लिए परिभाषित एक सरल उदाहरण है:

scala> List(1, 2, 3, 4, "5") collect {case x : Int => x + 42} 
res1: List[Int] = List(43, 44, 45, 46) 

collect तर्क के रूप में PartialFunction का एक उदाहरण ले जाता है और के सभी तत्वों पर लागू करता है संग्रह। हमारे मामले में फ़ंक्शन को केवल Ints और "5" फ़िल्टर करने के लिए परिभाषित किया गया है। तो, collectmap और filter का संयोजन है, जो वास्तव में आपका मामला है।

+1

'संग्रह' में मेरे लिए काम करता है वास्तव में 'फ़िल्टर' का संयोजन और फिर 'मानचित्र' का संयोजन होता है, लेकिन यह आमतौर पर अन्य दिशा ('मानचित्र' ** फिर **' फ़िल्टर') में काम नहीं करता है। , क्योंकि आपको केस स्टेटमेंट के गार्ड में फ़िल्टर को परिभाषित करने की आवश्यकता है। तो ओपी के पिछले दो कथनों को बदलने के लिए यह बहुत अच्छा होगा ('.collect {case some (x) => x}') के साथ, लेकिन यदि 'चेकर' में किसी भी प्रकार की गैर-तुच्छ गणना शामिल है, यह तय करने के लिए कि क्या वापस लौटना है या नहीं 'कुछ' या 'कोई नहीं', आंशिक फ़ंक्शन के रूप में लिखना मुश्किल हो सकता है। –

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