2011-12-04 6 views
15

यह एक नौसिखिया सवालस्केला: एक कार्यात्मक ढंग से संग्रह से एक वर जमा (है कि, कोई वार्स है)

है मैं निम्नलिखित कोड है:

var total = 0L 
docs.foreach(total += _.length) 

डॉक्स में मैं का एक संग्रह है .length संपत्ति के साथ वस्तुओं

मैं की तरह कुछ करना चाहते हैं:

val total = docs.[someScalaMethod](0, (element, acum) => acum + element.length) 

मेरा मतलब है, एक विधि है कि दोहराता प्रत्येक तत्व एक संचायक चर गुजर ...

पहले शून्य मैं संचायक वर का प्रारंभिक मूल्य होना चाहिए पारित ..

यह कैसे प्राप्त किया जा सकता?

+1

आपको http://stackoverflow.com/questions/2293592 सहायक भी मिल सकता है, लेकिन आपके प्रश्न को आपको वास्तव में पता होना चाहिए कि आपको क्या चाहिए, इसलिए आपको ट्यूटोरियल की आवश्यकता नहीं है - आपको बस यह जानने की जरूरत है कि क्या विधि कहा जाता है। –

+0

मैंने वैल डॉक्स लम्बाई = यदि (docs.length == 0) 0 अन्य docs.map (_। लंबाई) .sum के लिए अंतिम रूप से बस गए हैं लेकिन सभी उत्तर वास्तव में बहुत उपयोगी थे – opensas

+1

'docs.map (_। लंबाई) .sum' वही काम करेगा; 'sum' के लिए डिफ़ॉल्ट व्यवहार if/else है। –

उत्तर

22

यह एक गुना कहा जाता है। यह लगभग ठीक है कि तुम क्या कहा गया है:

docs.foldLeft(0)((accum, element) => accum + element.length) 
संस्करण है कि बाएं से दाएं (आमतौर पर बेहतर से संग्रह को पार करता लिए

; दाएं से बाएं foldRight है, और 2.9 एक fold कि कहीं भी शुरू कर सकते हैं है, लेकिन पर कैसे सीमाएँ हैं यह प्रकार को बदल सकता है)।

एक बार जब आप इसका उपयोग कर लेंगे, तो गुना बाएं का एक छोटा सा संस्करण है, जहां संचयक बाईं ओर जाता है (इसे लगता है कि इसे बाएं से दाएं सूची में धक्का दिया जाता है), और आप प्लेसहोल्डर का उपयोग करते हैं चर नाम के बाद से आप केवल उन्हें एक बार का उपयोग प्रत्येक: (0 /: docs)(_ + _.length)

+0

ऐरे के लिए फोल्ड विधि मौजूद नहीं है (ठीक है, यह मुझे मिली त्रुटि है) फ़ोल्डलिफ्ट का उपयोग करना था, और 0L को प्रारंभिक मान भी निर्दिष्ट करें, जैसे: docs.foldLeft (0 एल) ((acum, ele) => acum + ele.length) – opensas

+2

@ ओपेन्सस - आप स्कैला के पुराने संस्करण का उपयोग कर रहे हैं, मुझे लगता है; जैसा कि मुझे याद है, 'फोल्ड' 2.9 में पेश किया गया था। इससे पहले केवल बाएं और दाएं संस्करण थे। –

+0

आप सही हैं, स्कैला-वर्जन स्कैला कोड धावक संस्करण 2.8.1. फ़ाइनल - कॉपीराइट 2002-2010, LAMP/EPFL – opensas

8
docs map { _.length } reduce { _ + _ } 

या (tHX लुइगी Plinge को जाता है)

docs.map(_.length).sum 
+1

ध्यान दें कि यह 'विफल' खाली होने पर विफल रहता है, लेकिन अन्यथा एक सभ्य रणनीति है। –

+10

'docs.map (_। लंबाई) .sum' ... यह 2011 है! –

+0

स्कैला 2.9.1 के साथ, और पहली पसंद, मुझे निम्न त्रुटि मिलती है: त्रुटि: मान कम करना ऐरे का सदस्य नहीं है [लांग] वैल अनुवादित लम्बाई = अनुवादित मानचित्र {_.length} {_ + _} – opensas

3

यहाँ एक Scalaz संस्करण है:

docs.foldMap(_.length) 

यह docs.map(_.length).sum के बराबर है लेकिन केवल एक ही पास लेता है। इसके अलावा, सभी monoids के साथ काम करता है।

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