2009-07-30 11 views
8

(यह this Q&A के एक संस्करण है)संग्रह को मानचित्र-दर-कुंजी में बदलने का सबसे अच्छा तरीका है? (2 संस्करण)

मैं इस राशि कहते हैं:

List("foo", "bar", "spam") 

मैं एक मानचित्र जिसके लिए कुंजी स्ट्रिंग की लंबाई है बनाना चाहते हैं, और मूल्य है उस स्ट्रिंग के सभी स्ट्रिंग्स का संग्रह। दूसरे शब्दों में, के बारे में सूची को देखते हुए, हम पाते हैं:

Map(3 -> List(foo, bar), 4 -> List(spam)) 

कोड मैं यह करने के लिए लिखा गया है:

list.foldLeft(Map[Long, List[String]]()) { 
    (m, s) => m(s.length) = s :: 
    (if (m.contains(s.length)) m(s.length) 
     else Nil) 
} 

यह काम करता है, लेकिन यह करने के लिए कुरूपता का एक बहुत कहते हैं सुरुचिपूर्ण उत्तर डैनियल स्पिवाक ने मूल प्रश्न (उपरोक्त संदर्भित) को प्रदान किया।

कोई भी विचार मेरे संस्करण के लिए समाधान को बेहतर बनाने के लिए कैसे?

धन्यवाद! शॉन

उत्तर

7

आप घटिया प्रदर्शन कोई आपत्ति नहीं है:

val list = List("foo", "bar", "spam") 
val keyValue = for (length <- list map (_ length) removeDuplicates; 
        strings = list filter (_.length == length)) 
       yield (length -> strings) 
val map = Map(keyValue: _*) 

समस्या यह है कि इस सूची में प्रत्येक अलग लंबाई के लिए फिर से पढ़ने के लिए है है।

अब, अपने संस्करण की uglyness के बारे में है, शायद इस मदद करता है:

list.foldLeft(Map[Long, List[String]]()) { 
    (m, s) => m(s.length) = s :: m.getOrElse(s.length, Nil) 
} 

बेहतर? यह अभी भी काफी अच्छा नहीं है क्योंकि आपको लंबाई दो बार मिलती है। यह एक इस समस्या नहीं है, लेकिन यह थोड़ा भद्दा है:

list.foldLeft(Map[Long, List[String]]()) { 
    (m, s) => val length = s.length; m(length) = s :: m.getOrElse(length, Nil) 
} 
+0

मुझे अंतिम संस्करण बदसूरत नहीं लगता है, अगर वैल लंबाई को वैल एल के रूप में छोटा किया जाता है। स्कैला में एकल अक्षर चर अक्सर गणितीय सूत्रों के समान शैली में स्कैला में उपयोग किए जाते हैं, यानी आप प्लेसहोल्डर चर का अर्थ घोषित करते हैं, और फिर इसका उपयोग करें। क्योंकि इससे बहुत कम अभिव्यक्तियां होती हैं (अक्सर एक लाइनर), संक्षिप्त नाम जिसे अन्य भाषाओं में गुप्त माना जाएगा, अभ्यास में कोई समस्या नहीं है। – Palimondo

+0

@Palimondo यह लंबाई नहीं है जो मुझे परेशान करती है। मैं दो बयान में गणना को तोड़ने से नापसंद करता हूं। दुर्भाग्यवश, स्काला मूल्य का पुन: उपयोग करने के लिए 's.length' को अनुकूलित नहीं कर सकता, जैसा कि हास्केल होगा। –

19

स्काला 2.8.0 के साथ:

list.groupBy(_.length) 

ऐसा नहीं है कि किसी भी सरल नहीं मिल सकता है!

+0

मुझे लगता है कि यह बहुत ही सुरुचिपूर्ण है, लेकिन मुझे समझ में नहीं आता कि इस तरह की आवश्यकता क्यों है। क्या आप इसे समझा सकते हैं? धन्यवाद। – agilefall

+1

@agilefall: आप सही हैं। तरह की जरूरत नहीं है। धन्यवाद! –

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