2010-05-24 12 views
25

स्काला 2.7.7 का उपयोग करना:उच्च आदेश फ़ंक्शंस का उपयोग करके विकल्पों की सूची कैसे फ़्लैट करें?

अगर मैं विकल्प की एक सूची है, मैं उन्हें का उपयोग कर एक-समझ के लिए समतल कर सकते हैं:

val listOfOptions = List(None, Some("hi"), None) 
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None) 

scala> for (opt <- listOfOptions; string <- opt) yield string 
res0: List[java.lang.String] = List(hi) 

मैं इस शैली पसंद नहीं है, और नहीं बल्कि एक का प्रयोग करेंगे HOF।

scala> listOfOptions.flatMap(opt => if (opt.isDefined) Some(opt.get) else None) 
res1: List[java.lang.String] = List(hi) 

Intuitively मैं अपेक्षा की होगी काम करने के लिए निम्नलिखित है, लेकिन यह नहीं है:,

scala> List.flatten(listOfOptions) 
<console>:6: error: type mismatch; 
found : List[Option[java.lang.String]] 
required: List[List[?]] 
     List.flatten(listOfOptions) 

यहां तक ​​कि निम्नलिखित की तरह यह काम करना चाहिए लगता है, लेकिन नहीं करता है यह प्रयास भी स्वीकार किए जाने की वर्बोज़ है 'टी:

scala> listOfOptions.flatMap(_: Option[String]) 
<console>:6: error: type mismatch; 
found : Option[String] 
required: (Option[java.lang.String]) => Iterable[?] 
     listOfOptions.flatMap(_: Option[String]) 
         ^
सबसे अच्छा मैं के साथ आ सकते हैं

है:

scala> listOfOptions.flatMap(_.toList)   
res2: List[java.lang.String] = List(hi) 

... लेकिन मुझे विकल्प को सूची में बदलने की ज़रूरत नहीं है। यह गुंजाइश लगता है।

कोई सलाह?

उत्तर

46

स्काला 2.8 में, समतल काम करेगा:


Welcome to Scala version 2.8.0.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> val listOfOptions = List(None, Some("hi"), None) 
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None) 

scala> listOfOptions flatten 
res0: List[java.lang.String] = List(hi) 

यह 2.7.7 में काम नहीं करता है, हालांकि:


Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20). 

scala> val listOfOptions = List(None, Some("hi"), None) 
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None) 

scala> listOfOptions.flatten 
:6: error: no implicit argument matching parameter type (Option[java.lang.String]) => Iterable[Nothing] was found. 
     listOfOptions.flatten 

संग्रह पुस्तकालय बदल दिया गया है, और एक बहुत सुधार हुआ है 2.8 में, तो शायद आप नवीनतम स्कैला 2.8 आरसी का उपयोग करने की कोशिश कर सकते हैं और देख सकते हैं कि इससे आपके लिए उपयोग करना अधिक आसान हो जाता है या नहीं।

तुम सच में toList विधि का उपयोग नहीं करना चाहते हैं, तो मुझे लगता है कि आप भी इस तरह यह लिख सकते हैं:


scala> listOfOptions.flatMap(o => o) 
res: List[java.lang.String] = List(hi) 
नहीं

इसके अलावा शायद सुंदरता का एक बात है, लेकिन कम से कम यह 2.7 में काम करता है। 7।

+3

अरे हाँ। धन्यवाद! मैंने एक बार फ्लैटमैप (ओ => ओ) पर ठोकर खाई लेकिन तुरंत इसके बारे में भूल गई। क्यों flatMap (_) समान रूप से काम नहीं करता है साथ ही एक उत्सुक चीज भी है। – Synesso

18

अर्जन के जवाब की मदद के लिए स्काला 2.7.7 में आप List#flatten उपयोग कर सकते हैं, लेकिन आप प्रकार inferencer मदद करने के लिए की जरूरत है:

Welcome to Scala version 2.7.7.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> val listOfOptions = List(None, Some("hi"), None) 
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None) 

scala> listOfOptions.flatten[String]     
res0: List[String] = List(hi) 

scala> val x: List[String] = listOfOptions.flatten 
x: List[String] = List(hi) 
संबंधित मुद्दे