फ़िल्टर के बजाय फ़िल्टर


82

क्या फ़िल्टर के बजाय फ़िल्टर का उपयोग करना हमेशा अधिक प्रदर्शनकारी होता है, जब बाद में मानचित्र, फ़्लैटमैप आदि जैसे फ़ंक्शंस लागू होते हैं?

केवल मानचित्र, फ़्लैटमैप और फ़ॉरचेज़ ही क्यों समर्थित हैं? (अपेक्षित कार्य जैसे कि फ़ोर / साथ ही मौजूद हैं)


स्काला डॉक के इस भाग की भी विस्तृत व्याख्या है।
ओह्कट्स ११

जवाबों:


122

से स्काला डॉक्स :

नोट: के बीच का अंतर c filter pऔर c withFilter pहै कि पूर्व, एक नया संग्रह बनाता है जबकि बाद ही बाद के डोमेन को प्रतिबंधित करता है map, flatMap, foreach, और withFilterआपरेशनों।

तो filterमूल संग्रह को ले जाएगा और एक नया संग्रह तैयार withFilterकरेगा , लेकिन बाद में map/ flatMap/ withFilterकॉल के माध्यम से अनफ़िल्टर्ड मानों को गैर-सख्ती (यानी आलसी) पास करेगा, (फ़िल्टर्ड) संग्रह के माध्यम से एक दूसरे पास को बचाएगा। इसलिए यह बाद की विधि कॉल से गुजरते समय अधिक कुशल होगा।

वास्तव में, withFilterविशेष रूप से इन तरीकों की श्रृंखलाओं के साथ काम करने के लिए डिज़ाइन किया गया है, जो कि समझ के लिए डी-सुगर है। इसके लिए किसी अन्य तरीके (जैसे forall/ / exists) की आवश्यकता नहीं है, इसलिए उन्हें FilterMonadicरिटर्न प्रकार में नहीं जोड़ा गया है withFilter


आशा है कि वे अभी भी किसी दिन इन तरीकों को जोड़ते हैं।
किग्यो

1
@ किगियो मुझे नहीं लगता कि आप खुद के साथ प्रयोग करने वाले हैं (इसके अलावा भाव के लिए-अभिव्यक्तियों के अलावा)। viewयदि आप नक्शे / फ़िल्टर को आलसी होना चाहते हैं तो उपयोग करें ।
लुइगी प्लिंज

समझा। क्या के बीच सटीक अंतर viewऔर withFilter? देखने के लिए उपयोग क्यों नहीं किया जाता है for-loops?
किग्यो

5
बस संदर्भ के लिए, मुझे लगता है कि संग्रह - युक्तियाँ और चालें बकाया जानकारी प्रदान करती हैं। H5s को एंकर नहीं किया गया है, लेकिन आप Don’t create temporary collectionsलिंक किए गए सेक्शन में खोज सकते हैं ।
sthzg

4
के स्पष्ट उपयोग के बारे में withFilter, मार्टिन ओडस्की ने इसे स्पष्ट रूप से अपने स्कैला पाठ्यक्रमों में कोर्टेरा पर उपयोग किया है, जिसकी मैं अत्यधिक अनुशंसा करता हूं। यह देखते हुए कि वह ऐसा करता है, यह दूसरों को भी ऐसा करने के साथ आराम दे सकता है, हालांकि अंतर आमतौर पर केवल 1 वर्ण का है। उदाहरण के लिए seq.view filter pबनाम seq withFilter p
चक डेनियल

9

शैडोलैंड्स के उत्कृष्ट उत्तर के अलावा , मैं filterऔर के बीच के अंतर का एक सहज उदाहरण लाना चाहूंगा withFilter

चलो निम्नलिखित कोड पर विचार करें

val list = List(1, 2, 3)
var go = true
val result = for(i <- list; if(go)) yield {
   go = false
   i
}

अधिकांश लोग इसके resultबराबर होने की उम्मीद करते हैं List(1)। स्केल 2.8 के बाद से यह मामला है, क्योंकि इसके लिए समझ का अनुवाद किया गया है

val result = list withFilter {
  case i => go
} map {
  case i => {
    go = false
    i
  }
}

जैसा कि आप देख सकते हैं अनुवाद हालत को कॉल में बदल देता है withFilter। पहले स्केल 2.8 के लिए, समझ में निम्नलिखित की तरह कुछ में अनुवाद किया गया:

val r2 = list filter {
  case i => go
} map {
  case i => {
    go = false
    i
  }
}

का उपयोग करते हुए filter, का मूल्य resultकाफी अलग होगा List(1, 2, 3):। तथ्य यह है कि हम goध्वज बना रहे हैं falseइसका फ़िल्टर पर कोई प्रभाव नहीं है, क्योंकि फ़िल्टर पहले से ही किया गया है। फिर से, स्काला 2.8 में, इस मुद्दे का उपयोग करके हल किया गया है withFilter। जब withFilterउपयोग किया जाता है, तो हर बार किसी तत्व के किसी mapविधि के अंदर पहुंचने पर स्थिति का मूल्यांकन किया जाता है ।

संदर्भ : - पी। ११२०, स्काला इन एक्शन (कवर २.१०), मैनिंग पब्लिकेशंस, मिलंजन रायचौधुरी - ओडस्की के विचारों को समझने के लिए अनुवाद


1

मुख्य कारण क्योंकि forall / मौजूद नहीं है कि उपयोग मामला यह है कि:

  • आप आलसी के साथ लागू कर सकते हैं अनंत धारा / चलने के लिए
  • आप आलसी के साथ एक और आवेदन कर सकते हैं (और फिर से)

Forall को लागू करने के लिए / मौजूद होने के लिए हमें आलसीपन को खोते हुए सभी तत्वों को प्राप्त करने की आवश्यकता है।

उदाहरण के लिए:

import scala.collection.AbstractIterator

class RandomIntIterator extends AbstractIterator[Int] {
  val rand = new java.util.Random
  def next: Int = rand.nextInt()
  def hasNext: Boolean = true
}

//rand_integers  is an infinite random integers iterator
val rand_integers = new RandomIntIterator

val rand_naturals = 
    rand_integers.withFilter(_ > 0)

val rand_even_naturals = 
    rand_naturals.withFilter(_ % 2 == 0)

println(rand_even_naturals.map(identity).take(10).toList)

//calling a second time we get
//another ten-tuple of random even naturals
println(rand_even_naturals.map(identity).take(10).toList)

ध्यान दें कि ten_rand_even_naturals अभी भी एक पुनरावृत्ति है। केवल जब हम फोन toList यादृच्छिक संख्या पैदा किया और श्रृंखला में फ़िल्टर कर दिया जाएगा

ध्यान दें कि मानचित्र (पहचान) मानचित्र के बराबर है (i => i) और इसका उपयोग यहाँ किया जाता है ताकि किसी वस्तु को वापस मूल प्रकार में परिवर्तित किया जा सके (जैसे एक संग्रह, एक धारा, एक पुनरावृत्ति)


1

Forall / मौजूद भाग के लिए:

someList.filter(conditionA).forall(conditionB)

के रूप में ही होगा (हालांकि थोड़ा सा सहज ज्ञान युक्त)

!someList.exists(conditionA && !conditionB)

इसी तरह, .filter () मौजूद है () को एक अस्तित्व में जोड़ा जा सकता है () चेक?


-3

उपज का उपयोग करना, उदाहरण के लिए, एक काम हो सकता है:

for {
  e <- col;
  if e isNotEmpty
} yield e.get(0)

-5

वर्कअराउंड के रूप में, आप केवल mapऔर के साथ अन्य कार्यों को लागू कर सकते हैं flatMap

इसके अलावा, यह अनुकूलन छोटे संग्रह पर बेकार है ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.