विधेय द्वारा एक क्रम को दो टुकड़ों में कैसे विभाजित किया जाए?


120

मैं एक अनुक्रम को एक विधेय द्वारा दो सूचियों में कैसे विभाजित कर सकता हूं?

वैकल्पिक: मैं उपयोग कर सकते हैं filterऔर filterNot, या अपने ही विधि लिखते हैं, लेकिन वहाँ एक बेहतर और अधिक सामान्य (बिल्ट-इन) विधि नहीं है?

जवाबों:


194

partitionविधि का उपयोग करके :

scala> List(1,2,3,4).partition(x => x % 2 == 0)
res0: (List[Int], List[Int]) = (List(2, 4),List(1, 3))

1
val (even, odd) = List(1,2,3,4).partition(x => x % 2 == 0)partitionएक पठनीय तरीके से परिणामस्वरूप टपल को नष्ट करने का एक तरीका है।
k0pernikus

2
एक पार्टीशन के अंदर फंक्शन को छोटा कर सकता है _ % 2 == 0
k0pernikus

138

अच्छा partitionथा कि आप जिस चीज को चाहते थे - एक और तरीका है जो दो में एक सूची को विभाजित करने के लिए एक विधेय का उपयोग करता है span:।

पहला एक, विभाजन एक सूची में सभी "सत्य" तत्वों को रखेगा, और दूसरी सूची में अन्य।

स्पैन सभी तत्वों को एक सूची में तब तक डालेगा जब तक कि एक तत्व "झूठा" (विधेय के संदर्भ में) न हो। उस बिंदु से आगे, यह तत्वों को दूसरी सूची में डाल देगा।

scala> Seq(1,2,3,4).span(x => x % 2 == 0)
res0: (Seq[Int], Seq[Int]) = (List(),List(1, 2, 3, 4))

2
ठीक वही जो मेरे द्वारा खोजा जा रहा था। जब सूची को संबंधित मानदंड द्वारा आदेश दिया जाता है, तो यह बहुत अधिक समझ में आता है।
erich2k8

16

आप स्केलएक्स.ओआरजी पर एक नज़र डालना चाह सकते हैं - यह आपको उनके हस्ताक्षर द्वारा कार्यों के लिए स्काला मानक पुस्तकालय की खोज करने की अनुमति देता है। उदाहरण के लिए, निम्न टाइप करें:

List[A] => (A => Boolean) => (List[A], List[A])

आप विभाजन देखेंगे ।


10
scalex.org डोमेन वर्तमान में मृत है। लेकिन विकल्प है - scala-search.org ;-)।
मोन फेन

1
मछली पकड़ना सिखाना!
इस प्रयोग की मदद से

1
@monnef 2020 के लिए अपने विकल्प के लिए कोई विकल्प? :)
तहसीलियन

14

अगर आपको कुछ अतिरिक्त की आवश्यकता है तो आप फोल्डेफ्ट का भी उपयोग कर सकते हैं। मैंने इस तरह से कुछ कोड लिखे जब विभाजन ने इसे नहीं काटा:

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)
    }
  }

1
टपल और फोल्डेफ़्ट का उपयोग करने का बहुत अच्छा तरीका। मैंने दो सूचियों को कुशलतापूर्वक एक ही क्रम में रखने के लिए एक सूची सूची का उपयोग करके समाप्त किया, लेकिन अन्यथा मुझे जो चाहिए था, उसके लिए हाजिर था।
मैट हागोपियन

1

मुझे पता है कि मुझे पार्टी के लिए देर हो सकती है और अधिक विशिष्ट उत्तर हैं, लेकिन आप इसका अच्छा उपयोग कर सकते हैं 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)

यदि आप किसी गैर बूलियन में स्थिति को बदलने की जरूरत है, तो यह आपके कोड को थोड़ा और भविष्य का सबूत बनाता है।


0

यदि आप किसी सूची को 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"})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.