2011-03-17 80 views
0

如何通過「數組值」而不是單個值(簡單比較)過濾Arraycollection,下面的代碼片段用於通過單值進行過濾,現在我進入了過濾只有價格[10,4,1,8](來自主集合的一些隨機值)。 有沒有什麼更好的辦法由值Flex Filterfunction - 按數組值過濾

  private function filterForTestData(item:Object,filterBy:Array= [10,4,1,8]):Boolean{ 
       for(randomprice in filterBy) 
       return item.price == randomprice; 
} 
[Edited] 

的陣列應用過濾器做第二代碼片段

濾鏡功能簡單對比

  private function filterForTestData(item:Object):Boolean{ 
        if(item.price < slider.value) return true; 
        else return false;  
      } 

過濾

testData.filterFunction = filterForTestData; 
我沒有提到

[編輯]

的一點是我的filterBy陣列中的項目是自定義的數據不是基本數據類型。

回答

1

我打算回答這個問題,使用一個對象作爲查找,然後使用hasOwnProperty來確定屬性是否設置在過濾器對象上。從實際測試我的方法以及這兩個方法(創建一組模擬的數據字符串(其中100,000個),並且運行時方法之間的差異可以忽略不計(範圍在130和160毫秒之間)。所有這三個都有相同的運行時間

這裏是我的完整代碼,所以你可以亂七八糟,指出我是否做了一些使我的測試無效的事情,但這似乎對我有意義,使用indexOf它需要迭代直到它找到與hasOwnProperty相同的對象(假設純粹線性集合不是樹)(需要獲得所有屬性的列表並遍歷它們,除非有內置的機制來更有效地查找屬性:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
       layout="vertical" 
       height="100%" 
       width="100%" 
       xmlns:code="http://code.google.com/p/flex-iframe/" 
       creationComplete="application1_creationCompleteHandler(event)"> 

    <mx:Script> 
     <![CDATA[ 
      import flash.utils.getTimer; 

      import mx.collections.ArrayCollection; 
      import mx.events.FlexEvent; 

      /* private function filterForTestData(item:Object):Boolean{ 
       return filterBy.hasOwnProperty(item); 
      } */ 
      /* private function filterForTestData(item:Object):Boolean{ 
       return filterBy.indexOf(item) != -1; 
      } */ 
      private function filterForTestData(item:Object):Boolean{ 
       for(var randomprice in filterBy) 
        return item == randomprice; 
       return false; 
      } 

      [Bindable] 
      private var dp:ArrayCollection = new ArrayCollection(['1','2','3','4','5','6','7','8']); 
      private var filterBy:Object={'10':true,'4':true,'1':true,'8':true}; 
      //private var filterBy:Array= ['10','4','1','8']; 
      protected function button2_clickHandler(event:MouseEvent):void 
      { 
       // TODO Auto-generated method stub 
       var startTime:int = getTimer(); 
       trace(getTimer()); 
       dp.filterFunction = filterForTestData; 
       dp.refresh(); 
       var endTime:int = getTimer(); 
       trace("total time: " + (endTime-startTime).toString()); 
      } 


      protected function application1_creationCompleteHandler(event:FlexEvent):void 
      { 
       // TODO Auto-generated method stub 
       for(var i:int=0;i<100000;i++) 
       { 
        dp.addItem(Math.floor(Math.random()*100).toString()); 
       } 
       theList.dataProvider = dp; 
      } 

     ]]> 
    </mx:Script> 
    <mx:List id="theList" width="100"/> 
    <mx:Button click="button2_clickHandler(event)"/> 
</mx:Application> 

我會試着從純數據的角度思考這個問題,看看是否有可能獲得比這更好的運行時間,或者它只是需要一定數量的檢查的問題的本質(漸近分析)。

好問題。

[編輯] 好了,經過深思熟慮之後,我相信不需要使用更復雜的數據結構(並且在創建/重新組織數據結構時引發處理器時間成本...考慮保持平衡樹搜索)我敢肯定,任何方法都會導致與這些方法相當或更差的運行時間(即線性運行時間或更差的O(n))。使用Tree結構可以使搜索的運行時間爲O(log n),但在保持樹平衡(根據需要進行旋轉)時會產生更多的處理開銷。如果任何人都可以使這個聲明失效,如果你這樣做,我會很高興,但我相信這是完全正確的。我沒有提到

http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/binarySearchTree.htm

1

爲什麼不使用Array的indexof方法?

private function filterForTestData(item:Object,filterBy:Array= [10,4,1,8]):Boolean{ 
    return filterBy.indexof(item.price) != -1; 
} 

(它檢查,如果該項目的價格值是filterBy陣列中找到。如果不是,則indexof方法返回-1。否則,它將返回數組的索引。)

我還沒有測試過 - 你可能必須將item.price轉換爲數字類型,但我不確定。

+0

的一點是我的filterBy陣列中的項目是自定義的數據不是基本數據類型。仍然indexof將工作? – Anandh 2011-03-17 16:40:32

+0

這是一件值得注意的事情。我相信只有當被比較的兩個對象具有相同的參考時(例如,是相同的對象),它纔會起作用。當搜索搜索對象的索引時,indexof方法使用嚴格的等式:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#indexOf%28%29。 – bedwyr 2011-03-17 16:52:57