2011-04-05 9 views
5

स्काला बहुत ही सुंदर है निकालें:स्केला ArrayBuffer अपरिवर्तनीय दृश्यों को छानने में एक predicat साथ सभी तत्वों

var l = List(1,2,3,4,5,6) 
l = l.filter(_%2==1) 

लेकिन मैं कैसे ArrayBuffer की तरह एक परिवर्तनशील संग्रह के साथ ऐसा कर सकता हूं? मुझे जो भी मिला वह एकल तत्वों या स्लाइसों को हटाने, या किसी अन्य अनुक्रम से तत्वों को हटा रहा है, लेकिन कुछ भी नहीं जो भविष्यवाणी द्वारा दिए गए तत्वों को हटा देता है।

संपादित करें: मैं इस यद्यपि कुछ इसी तरह लगता है उम्मीद थी: रैखिक समय में

trait Removable[A] extends Buffer[A]{ 
    def removeIf(p: A => Boolean){ 
    var it1 = 0 
    var it2 = 0 

    while(it2 < length){ 
     if(p(this(it2))){ 
     it2 += 1; 
     } 
     else { 
     this(it1) = this(it2) 
     it1 += 1; 
     it2 += 1; 
     } 
    } 

    trimEnd(it2-it1) 
    } 
} 

इस फिल्टर और किसी भी बफर में मिलाया जा सकता है, लेकिन केवल ArrayBuffer, समझ में आता है ListBuffers यह धीमी गति से किया जाएगा पर, क्योंकि अनुक्रमण रैखिक समय लेता है।

उत्तर

3

मेरा अनुमान है कि एक नया बफर बनाकर फ़िल्टर करना अधिक कुशल है, इसलिए आप आमतौर पर filter का उपयोग करेंगे और इसके परिणाम का उपयोग करेंगे। नहीं तो आप अपनी खुद की यथा-स्थान फिल्टर विधि लिख सकते हैं:

def filterInPlace[A](b: collection.mutable.Buffer[A])(fun: A => Boolean): Unit = { 
    var sz = b.size 
    var i = 0; while(i < sz) { 
    if (fun(b(i))) { 
     i += 1 
    } else { 
     sz -= 1 
     b.remove(i) 
    } 
    } 
} 

val b = collection.mutable.ArrayBuffer((1 to 6): _ *) 
filterInPlace(b)(_ % 2 == 1) 
println(b) 
+1

के साथ आया था आपका 'filterInPlace', धीमी है क्योंकि' b.remove (i) 'एक हे (एन) विधि है। –

1

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

+0

मुझे लगता है कि मैं जोर से पर्याप्त मांग नहीं कर रहा हूं, या मेरे बहुत कम हैं। –

+0

@Rex मैं बस उन्हें लागू करने और स्कैला इनक्यूबेटर को सबमिट करने का इंतजार कर रहा हूं। :-) वास्तव में, ईपीएफएल लोगों के पास सीमित संसाधन हैं, और कुछ महत्वपूर्ण चीजें छोड़ दी गई हैं। उदाहरण के लिए, '-सेव' का भाग्य देखें। –

+0

मैंने व्यावहारिक रूप से स्केल-बहस धागे में खुद को लिखने की पेशकश की, मैंने कुछ महीने पहले शुरू किया था। हो सकता है कि आप सही हों और इतनी कम मांग है कि किसी और को इसे लागू करने के लिए पूछना भी उचित नहीं है। –

0

अक्सर withFilter पर्याप्त है, खासकर अगर बफर को अंत में एक अपरिवर्तनीय संरचना में परिवर्तित किया जाता है। सच है, यह वास्तव में तत्वों को हटा नहीं देता है, लेकिन कम से कम यह एक नया ArrayBuffer ऑब्जेक्ट नहीं बनाता है।

0

यह मेरे लिए काम किया है, लेकिन केवल के साथ क्लोन(), इस प्रकार अभी भी :-)

scala> import collection.mutable.ArrayBuffer 
import collection.mutable.ArrayBuffer 

scala> val buf = ArrayBuffer(1,2,3,4,5,6,7,8,9,10) 
buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 

scala> buf.clone foreach { x => if (x > 4) buf -= x } 

scala> buf 
res1: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4) 

लेकिन बेहतर तरीका एक नया ArrayBuffer बनाने केवल उन तत्वों की एक नई सरणी, जो आप चाहते हैं बनाने के लिए किया जाएगा दूर करने के लिए (इस प्रकार पूरे बफर नकल नहीं) और फिर उन्हें हटाने:

scala> val buf = ArrayBuffer(1,2,3,4,5,6,7,8,9,10) 
buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 

scala> buf filter { _ > 4 } foreach { buf -= _ } 

scala> buf 
res3: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4) 
+0

हाँ आपका समाधान काम करेगा, लेकिन यह समय ओ (एन^2) में होगा, क्योंकि प्रत्येक निकालना एक खोज और बफर का पुनर्गठन है।मैं कुछ ऐसा ढूंढ रहा था जो ओ (एन) में काम करता है। लेकिन मुझे लगता है कि मुझे इसे खुद करने की ज़रूरत है। – Arne

+0

मुझे लगता है कि यहां परिवर्तनीय मामले में यह कभी भी ओ (एन) नहीं होगा। लेकिन यदि आप क्लासिक अपरिवर्तनीय फ़िल्टर करते हैं, तो आपके पास ओ (एन) :-) में है। –

1

आप इसे ArrayBuffer साथ भी ऐसा ही। सभी संग्रह वर्गों में एक ही तरीके उपलब्ध हैं।

1

मैं इस

import scala.collection.mutable 

trait BufferUtils { 
    import BufferUtils._ 
    implicit def extendMutableBuffer[T](org: mutable.Buffer[T]): ExtendedBuffer[T] = new ExtendedBuffer(org) 
} 

object BufferUtils extends BufferUtils { 

    implicit class ExtendedBuffer[T](val org: mutable.Buffer[T]) extends AnyVal { 
     def removeIf(pred: (T) => Boolean): Unit = { 
      // target holds the index we want to move the next element to 
      var target = 0 

      for (i <- org.indices; 
       elem = org(i) 
       if !pred(elem)) { 

       org(target) = elem 
       target += 1 
      } 

      org.remove(target, org.size - target) 
     } 
    } 

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