क्या 2 नई सूचियां बनाने के लिए collect
पर एक कॉल का उपयोग करना संभव है? यदि नहीं, तो मैं partition
का उपयोग करके यह कैसे कर सकता हूं?स्कैला विभाजन/उपयोग एकत्र करें
उत्तर
collect
(सभी उपवर्गों में TraversableLike पर परिभाषित और उपलब्ध है) संग्रह के साथ काम करता है और PartialFunction
। यह भी सिर्फ इतना है कि मामले खंड ब्रेसिज़ के अंदर परिभाषित के एक समूह के एक आंशिक समारोह (Scala Language Specificationकी धारा 8.5 देखें [चेतावनी - पीडीएफ]) कर रहे हैं
अपवाद संचालन में के रूप में:
try {
... do something risky ...
} catch {
//The contents of this catch block are a partial function
case e: IOException => ...
case e: OtherException => ...
}
यह एक फ़ंक्शन को परिभाषित करने का एक आसान तरीका जो केवल किसी दिए गए प्रकार के कुछ मान स्वीकार करेगा।
मिश्रित मानों की सूची पर उपयोग पर विचार करें:
val mixedList = List("a", 1, 2, "b", 19, 42.0) //this is a List[Any]
val results = mixedList collect {
case s: String => "String:" + s
case i: Int => "Int:" + i.toString
}
तर्क collect
करने के लिए विधि एक PartialFunction[Any,String]
है। PartialFunction
क्योंकि यह Any
(List
का प्रकार होने) और String
के सभी संभावित इनपुट के लिए परिभाषित नहीं है क्योंकि यह सभी खंड वापस आते हैं।
आप collect
के बजाय map
उपयोग करने का प्रयास करते हैं, तो mixedList
के अंत में डबल मूल्य एक MatchError
का कारण होगा। collect
का उपयोग करके बस इसे छोड़ दें, साथ ही साथ कोई अन्य मान जिसके लिए पार्टिकल फ़ंक्शन परिभाषित नहीं किया गया है। इस तरह एक युद्ध अपराध होने के लिए कई द्वारा माना जाता है हालांकि यह सिर्फ एक उदाहरण है
var strings = List.empty[String]
var ints = List.empty[Int]
mixedList collect {
case s: String => strings :+= s
case i: Int => ints :+= i
}
, परिवर्तनशील वैरिएबल का उपयोग कर - इसलिए कृपया:
एक संभावित उपयोग सूची के तत्वों को अलग तर्क लागू करने के लिए किया जाएगा ऐसा मत करो!
एक ज्यादा बेहतर समाधान दो बार इकट्ठा उपयोग करने के लिए है:
val strings = mixedList collect { case s: String => s }
val ints = mixedList collect { case i: Int => i }
या यदि आप कुछ के लिए पता है कि इस सूची में केवल मूल्यों के दो प्रकार के होते हैं, आप partition
, जो मूल्यों में एक संग्रह विभाजन का उपयोग कर सकते चाहे या नहीं वे कुछ विधेय से मेल खाते हैं पर निर्भर करता है:
//if the list only contains Strings and Ints:
val (strings, ints) = mixedList partition { case s: String => true; case _ => false }
यहाँ पकड़ है कि दोनों strings
और ints
प्रकारके हैं, यद्यपि आप आसानी से उन्हें कुछ और प्रकारों पर वापस कर सकते हैं (शायद collect
का उपयोग करके ...)
यदि आपके पास पहले से ही एक प्रकार का सुरक्षित संग्रह है और तत्वों की किसी अन्य संपत्ति पर विभाजित करना चाहते हैं, तो चीजें हैं आपके लिए थोड़ा आसान:
val intList = List(2,7,9,1,6,5,8,2,4,6,2,9,8)
val (big,small) = intList partition (_ > 5)
//big and small are both now List[Int]s
आशा है कि यह बताता है कि दोनों विधियां यहां आपकी मदद कैसे कर सकती हैं!
कैसे परिवर्तनशील सूचियों का उपयोग किए बिना collect
साथ यह करने के लिए है, लेकिन partition
के रूप में अच्छी तरह से (सिर्फ एक छोटे से अधिक शब्द) मिलान पैटर्न का उपयोग कर सकते हैं सुनिश्चित नहीं हैं कि
List("a", 1, 2, "b", 19).partition {
case s:String => true
case _ => false
}
@coubeatczech - क्योंकि विभाजन एक रिटर्न '(सूची [एक], सूची [एक])'। यह सब कुछ कर सकता है क्योंकि इनपुट 'सूची [ए]' और एक सूचक कार्य 'ए => बूलियन' है। इसका यह जानने का कोई तरीका नहीं है कि सूचक कार्य प्रकार-विशिष्ट हो सकता है। –
@Rex मैंने अपने स्वयं के 'कोलेट' विधि को उन संग्रहों पर भंग करने के लिए परिभाषित किया जो इस समस्या को हल करते हैं। 'सूची [ए]' पर उपयोग-केस हस्ताक्षर 'कोलेट [बी] (एफएन: आंशिक समारोह [ए, बी]): (सूची (बी), सूची (ए)), जाहिर है * वास्तविक * हस्ताक्षर है इससे थोड़ा बालों वाला है क्योंकि मैं 'CanBuildFrom' –
सामान्य रूप से इस्तेमाल किया collect
पर, कहते हैं, Seq
के हस्ताक्षर,
collect[B](pf: PartialFunction[A,B]): Seq[B]
जो वास्तव में
collect[B, That](pf: PartialFunction[A,B])(
implicit bf: CanBuildFrom[Seq[A], B, That]
): That
तो की एक विशेष विषय है यदि आप डिफ़ॉल्ट मोड में इसका इस्तेमाल होता है, जवाब नहीं है, निश्चित रूप से नहीं: आपको इससे बिल्कुल एक अनुक्रम मिलता है। यदि आप CanBuildFrom
Builder
के माध्यम से अनुसरण करते हैं, तो आप देखते हैं कि That
वास्तव में दो अनुक्रमों को बनाना संभव होगा, लेकिन यह कहने का कोई तरीका नहीं होगा कि किसी अनुक्रम को किस क्रम में जाना चाहिए, क्योंकि आंशिक कार्य केवल "हाँ, मैं कह सकता हूं" संबंधित "या" नहीं, मैं संबंधित नहीं हूं "।
तो आप क्या करते हैं यदि आप कई स्थितियां चाहते हैं जिसके परिणामस्वरूप आपकी सूची अलग-अलग टुकड़ों के समूह में विभाजित हो? एक तरीका एक सूचक फ़ंक्शन A => Int
बनाना है, जहां आपका A
एक क्रमांकित वर्ग में मैप किया गया है, और उसके बाद groupBy
का उपयोग करें। उदाहरण के लिए:
def optionClass(a: Any) = a match {
case None => 0
case Some(x) => 1
case _ => 2
}
scala> List(None,3,Some(2),5,None).groupBy(optionClass)
res11: scala.collection.immutable.Map[Int,List[Any]] =
Map((2,List(3, 5)), (1,List(Some(2))), (0,List(None, None)))
अब आप अपनी उप-सूचियां इस मामले में कक्षा (0, 1, और 2) देख सकते हैं। दुर्भाग्यवश, यदि आप कुछ इनपुटों को अनदेखा करना चाहते हैं, तो आपको अभी भी उन्हें एक कक्षा में रखना होगा (उदाहरण के लिए आपको शायद इस मामले में None
की कई प्रतियों की परवाह नहीं है)।
मैं इसका उपयोग करता हूं। इसके बारे में एक अच्छी बात यह है कि यह एक पुनरावृत्ति में विभाजन और मैपिंग को जोड़ती है। एक दोष यह है कि यह अस्थायी वस्तुओं का एक समूह (Either.Left
और Either.Right
उदाहरणों)
/**
* Splits the input list into a list of B's and a list of C's, depending on which type of value the mapper function returns.
*/
def mapSplit[A,B,C](in: List[A])(mapper: (A) => Either[B,C]): (List[B], List[C]) = {
@tailrec
def mapSplit0(in: List[A], bs: List[B], cs: List[C]): (List[B], List[C]) = {
in match {
case a :: as =>
mapper(a) match {
case Left(b) => mapSplit0(as, b :: bs, cs )
case Right(c) => mapSplit0(as, bs, c :: cs)
}
case Nil =>
(bs.reverse, cs.reverse)
}
}
mapSplit0(in, Nil, Nil)
}
val got = mapSplit(List(1,2,3,4,5)) {
case x if x % 2 == 0 => Left(x)
case y => Right(y.toString * y)
}
assertEquals((List(2,4),List("1","333","55555")), got)
आवंटित करता है मैं यहाँ इस बुनियादी समस्या के लिए एक संतोषजनक समाधान नहीं मिल सका है। मुझे collect
पर व्याख्यान की आवश्यकता नहीं है और यह परवाह नहीं है कि यह किसी का होमवर्क है या नहीं। साथ ही, मुझे ऐसा कुछ नहीं चाहिए जो केवल List
के लिए काम करता हो।
तो यहां मेरा स्टैब है। कुशल और किसी भी TraversableOnce
के साथ संगत, यहां तक कि तार:
implicit class TraversableOnceHelper[A,Repr](private val repr: Repr)(implicit isTrav: Repr => TraversableOnce[A]) {
def collectPartition[B,Left](pf: PartialFunction[A, B])
(implicit bfLeft: CanBuildFrom[Repr, B, Left], bfRight: CanBuildFrom[Repr, A, Repr]): (Left, Repr) = {
val left = bfLeft(repr)
val right = bfRight(repr)
val it = repr.toIterator
while (it.hasNext) {
val next = it.next
if (!pf.runWith(left += _)(next)) right += next
}
left.result -> right.result
}
def mapSplit[B,C,Left,Right](f: A => Either[B,C])
(implicit bfLeft: CanBuildFrom[Repr, B, Left], bfRight: CanBuildFrom[Repr, C, Right]): (Left, Right) = {
val left = bfLeft(repr)
val right = bfRight(repr)
val it = repr.toIterator
while (it.hasNext) {
f(it.next) match {
case Left(next) => left += next
case Right(next) => right += next
}
}
left.result -> right.result
}
}
उदाहरण उपयोगों:
val (syms, ints) =
Seq(Left('ok), Right(42), Right(666), Left('ko), Right(-1)) mapSplit identity
val ctx = Map('a -> 1, 'b -> 2) map {case(n,v) => n->(n,v)}
val (bound, unbound) = Vector('a, 'a, 'c, 'b) collectPartition ctx
println(bound: Vector[(Symbol, Int)], unbound: Vector[Symbol])
- 1. दो पूर्णांक सरणी एकत्र करें
- 2. ग्राहक प्रतिक्रिया कैसे एकत्र करें?
- 3. सिस्टम और पर्यावरण की जानकारी एकत्र करें
- 4. Grails: सभी संदेशों को कैसे एकत्र करें
- 5. Powershell कस्टम वस्तुओं: एकत्र परिणाम
- 6. MySQL (कॉलम द्वारा) में एकाधिक क्वेरी परिणाम एकत्र करें
- 7. Django: केवल बदली गई स्थिर फाइलें एकत्र करें
- 8. मैकॉक्स: स्थानीय बंडल में निर्भरता कैसे एकत्र करें?
- 9. जब MVAr कचरा एकत्र किया जाता है
- 10. स्कैला
- 11. स्कैला
- 12. स्कैला
- 13. स्कैला
- 14. स्कैला
- 15. स्कैला
- 16. स्कैला
- 17. सी #: वीक रेफरेंस एकत्र करने से पहले अधिसूचना एकत्र की जाती है?
- 18. स्कैला
- 19. स्कैला
- 20. स्कैला
- 21. स्कैला मानचित्र कैसे पुनरारंभ करें?
- 22. स्कैला - आरईपीएल पर्यावरण शुरू करें
- 23. स्कैला आरईपीएल प्रोग्रामेटिक लॉन्च करें?
- 24. स्कैला
- 25. स्कैला
- 26. स्कैला
- 27. स्कैला
- 28. स्कैला
- 29. स्कैला
- 30. स्कैला कनवर्ट करें मानचित्र पर सेट करें
का भी उपयोग कर रहा हूं बहुत अच्छी व्याख्या, लेकिन मुझे लगता है कि ओपी चाहता है कि' संग्रह 'और' विभाजन 'का संयोजन है जो एकत्रित मूल्यों और सूची की सूची का एक टुपल देता है बाकी सभी का। 'def संग्रह और विभाजन [ए, बी] (पीएफ: आंशिक समारोह [ए, बी]): (सूची [बी], सूची [ए])'। यह मूल रूप से देशी लाइब्रेरी फ़ंक्शन के साथ सबसे सुंदर रूप से हासिल किया जाएगा, यानी ट्रैवर्सबल में 'संग्रह' के स्रोत में हमारे पास 'x <- this) है (pf.isDefinedAt (x)) b + = pf (x) ' , कोई भी उस के अंत में 'else a + = x' को आसानी से ले सकता है, जहां' बाकी 'बाकी की सूची के लिए एक निर्माता होगा। –
मुझे पता है कि ओपी को क्या चाहिए, और मुझे यह भी पता है कि यह एक होमवर्क प्रश्न है (हाल ही में स्टैक ओवरफ्लो पर इसका उल्लेख किया गया है), इसलिए मैं वास्तव में इसे हल किए बिना बहुत सारे सिद्धांत प्रदान करूंगा। संग्रह और विभाजन के लिए, मैंने पहले से ही लिखा है, हालांकि मैंने विधि 'कोलेट' नाम दिया है।यदि कोई उस स्तर पर स्कैला पढ़ रहा है जहां छात्रों को CanBuildFrom के साथ काम करने की उम्मीद है तो मैं बहुत आश्चर्यचकित हूं, यह वर्तमान में उत्पादन में स्कैला का उपयोग करने वाले अधिकांश लोगों से परे है। –
वह बहुत उपयोगी था। लेकिन मैं अभी भी सोच रहा हूं ... क्या आप "युद्ध अपराध" के बिना सकारात्मक और नकारात्मक मूल्यों को अलग करना संभव है, जैसा आपने लिखा था? मैं सिर्फ उत्सुक हूं क्योंकि मैंने विभाजन का उपयोग करने के साथ पहले ही होमवर्क किया है। ओह ... और वैसे, मदद के लिए धन्यवाद! –