मैं एक अनुक्रम को एक विधेय द्वारा दो सूचियों में कैसे विभाजित कर सकता हूं?
वैकल्पिक: मैं उपयोग कर सकते हैं filter
और filterNot
, या अपने ही विधि लिखते हैं, लेकिन वहाँ एक बेहतर और अधिक सामान्य (बिल्ट-इन) विधि नहीं है?
मैं एक अनुक्रम को एक विधेय द्वारा दो सूचियों में कैसे विभाजित कर सकता हूं?
वैकल्पिक: मैं उपयोग कर सकते हैं filter
और filterNot
, या अपने ही विधि लिखते हैं, लेकिन वहाँ एक बेहतर और अधिक सामान्य (बिल्ट-इन) विधि नहीं है?
जवाबों:
partition
विधि का उपयोग करके :
scala> List(1,2,3,4).partition(x => x % 2 == 0)
res0: (List[Int], List[Int]) = (List(2, 4),List(1, 3))
_ % 2 == 0
।
अच्छा partition
था कि आप जिस चीज को चाहते थे - एक और तरीका है जो दो में एक सूची को विभाजित करने के लिए एक विधेय का उपयोग करता है span
:।
पहला एक, विभाजन एक सूची में सभी "सत्य" तत्वों को रखेगा, और दूसरी सूची में अन्य।
स्पैन सभी तत्वों को एक सूची में तब तक डालेगा जब तक कि एक तत्व "झूठा" (विधेय के संदर्भ में) न हो। उस बिंदु से आगे, यह तत्वों को दूसरी सूची में डाल देगा।
scala> Seq(1,2,3,4).span(x => x % 2 == 0)
res0: (Seq[Int], Seq[Int]) = (List(),List(1, 2, 3, 4))
आप स्केलएक्स.ओआरजी पर एक नज़र डालना चाह सकते हैं - यह आपको उनके हस्ताक्षर द्वारा कार्यों के लिए स्काला मानक पुस्तकालय की खोज करने की अनुमति देता है। उदाहरण के लिए, निम्न टाइप करें:
List[A] => (A => Boolean) => (List[A], List[A])
आप विभाजन देखेंगे ।
अगर आपको कुछ अतिरिक्त की आवश्यकता है तो आप फोल्डेफ्ट का भी उपयोग कर सकते हैं। मैंने इस तरह से कुछ कोड लिखे जब विभाजन ने इसे नहीं काटा:
val list:List[Person] = /* get your list */
val (students,teachers) =
list.foldLeft(List.empty[Student],List.empty[Teacher]) {
case ((acc1, acc2), p) => p match {
case s:Student => (s :: acc1, acc2)
case t:Teacher => (acc1, t :: acc2)
}
}
मुझे पता है कि मुझे पार्टी के लिए देर हो सकती है और अधिक विशिष्ट उत्तर हैं, लेकिन आप इसका अच्छा उपयोग कर सकते हैं groupBy
val ret = List(1,2,3,4).groupBy(x => x % 2 == 0)
ret: scala.collection.immutable.Map[Boolean,List[Int]] = Map(false -> List(1, 3), true -> List(2, 4))
ret(true)
res3: List[Int] = List(2, 4)
ret(false)
res4: List[Int] = List(1, 3)
यदि आप किसी गैर बूलियन में स्थिति को बदलने की जरूरत है, तो यह आपके कोड को थोड़ा और भविष्य का सबूत बनाता है।
यदि आप किसी सूची को 2 से अधिक टुकड़ों में विभाजित करना चाहते हैं, और सीमा को अनदेखा करते हैं, तो आप इस तरह से कुछ का उपयोग कर सकते हैं (संशोधित करें यदि आपको ints की तलाश करने की आवश्यकता है)
def split(list_in: List[String], search: String): List[List[String]] = {
def split_helper(accum: List[List[String]], list_in2: List[String], search: String): List[List[String]] = {
val (h1, h2) = list_in2.span({x: String => x!= search})
val new_accum = accum :+ h1
if (h2.contains(search)) {
return split_helper(new_accum, h2.drop(1), search)
}
else {
return accum
}
}
return split_helper(List(), list_in, search)
}
// TEST
// split(List("a", "b", "c", "d", "c", "a"), {x: String => x != "x"})
val (even, odd) = List(1,2,3,4).partition(x => x % 2 == 0)
partition
एक पठनीय तरीके से परिणामस्वरूप टपल को नष्ट करने का एक तरीका है।