4 Replies Latest reply on Jul 29, 2011 11:02 AM by UbuntuPenguin

    ArrayCollection Filter creates ghost data

    LoganSix Level 1

      I have a Flex 3 application that brings in xml data and stores it into an ArrayCollection.  Initial row count is 21 rows.

      I filter this ArrayCollection on a date range.  The Current Month row count is 1 row.

       

      So far so good.  Then I need to get the number of times a particular value shows up in a column for that data set.  First, I filter the column for unique values.

      public static function getUniqueValues (collection:ArrayCollection, propertyName:String):ArrayCollection {
                     var length:Number = collection.length;
                     var dict:Dictionary = new Dictionary();
                     
                     //this should be whatever type of object you have inside your AC
                     var obj:Object;
                     for(var i:int = 0; i < length; i++){
                          obj = collection.getItemAt(i);
                          
                          dict[obj[propertyName]] = obj[propertyName];
                     }
                     
                     //this bit goes through the dictionary and puts data into a new AC
                     var unique:ArrayCollection = new ArrayCollection();
                     for(var propertyString:String in dict){
                          unique.addItem(dict[propertyString]);
                     }
                     return unique;
                }
      

       

      This returns back 1 value for the Current Month, since there is only one row in the filtered ArrayCollection.

       

      Then I send this ArrayCollection to find out how many times it shows up in the ArrayCollection.

                public static function getValueCounts(vcSourceCollection:ArrayCollection, vcValueCollection:ArrayCollection, propertyName:String):ArrayCollection {
                     var length:Number = vcValueCollection.length;
                     var cvReturnArray:ArrayCollection =  new ArrayCollection();
                     var filterValue:String;
                     
                     var vcFilterFunction:Function = function(item:Object):Boolean {
                        return item[propertyName].toString().toLocaleLowerCase() == filterValue.toLocaleLowerCase();
                    }
                     
                     for(var i:int = 0; i < length; i++){
                          filterValue = vcValueCollection.getItemAt(i).toString();
                          vcSourceCollection.filterFunction = vcFilterFunction;
                          vcSourceCollection.refresh();
                          
      
                          var countObject:Object = new Object();
                          countObject.name = vcValueCollection.getItemAt(i);
                          countObject.value = vcSourceCollection.length;
                          cvReturnArray.addItem(countObject);
                     }
                     
                     return cvReturnArray;
                }
      

       

      In normal operation it should return back 1 row, with name = Item1 and value = 1.

      However, if I keep the vcSourceCollection.refresh() in, it returns back and extra 6 rows of data.  Some how, extra data appears in the vcSourceCollection.  If I remove the refresh(), then it doesn't appear, but it also doesn't do the filter.

       

      I appreciate any ideas on why this is happening.  This is probably some major bug with Flex 3, but I can't upgrade at the moment.

      This is for work, so I can't post the data or provide a link to the test application.

        • 1. Re: ArrayCollection Filter creates ghost data
          UbuntuPenguin Level 4

          Who ya gonna call ?!

           

          In the fucntion "getValueCounts", you are adding the filter to the same collection for every loop iterations.

          But if I remember correctly filterfunctions don't stack so the last filter that is added is the one that applies.  With that knowledge, I would begin investigating the return value of the filter function.

           

          The code seems kind of "spooky" , especially with the way you are filtering based on an item from your iterator value(i) then you grab that same item at the iterator index on your filtered collection ? Would you mind telling us what your end goal is, there might be a less cumbersome way to acheive it.

          • 2. Re: ArrayCollection Filter creates ghost data
            LoganSix Level 1

            The following data, for example, is held in the Initial Array.  Not the complete dataset, but just to give you a basic idea.

            IDTitleDefectWhen Defect Found
            Product
            Creation Date
            1Item 1ElectricalTestX001Jul 1, 2011
            2Item 4MechanicalTestX002Jun 1, 2011
            3Item 5SoftwareAcceptanceX003Jun 20, 2011
            4Item 6SoftwareReviewX001May 1, 2011
            5Item 10ElectricalAcceptanceX004Apr 10, 2011
            6Item 11ElectricalBuildX005Feb 23, 2011
            7Item 12MechanicalBuildX002Jan 25, 2011
            8Item 20SoftwareTestX001Jun 15, 2011

             

            The display shows a DataGrid, Perado Chart and a Pie Chart.

             

            The DataGrid shows a subset of the columns (i.e., only showing certain columns) which is handle in the DataGrid setup.

            The Perado Chart and the Pie Chart show the Search value and the number of times it shows in the dataset.

            The Initial Array dataset is initially filtered by a date range (i.e. This Month, Last Month, This Quarter, Last Quarter, This Year, Last Year).

             

            So, for exmaple, on initial display it shows This Month's data, which would only have 1 row.

            The initial Search value is "Defect", so there should be 1 Electrical Defect for This Month.

            The Pie Chart and Perado Chart would show "Electrical" with 1 as the value.

             

            The iterator value for "Defect" would look like this

            Unique Value
            Software
            Mechanical
            Electrical

             

            If I were to get all Defect counts for all dates, then the final data would look like this.

            ValueCount
            Software3
            Mechanical3
            Electrical2

             

             

             

            There is a ComboBox that the user can change the Search value [Defect, When Defect Found, Product], which is has the data value of the Column name.

             

            So, in steps

            1. Retrieves xml and puts into Inital Array
            2. Filters Inital Array by Date Range
            3. Finds Unique Values in Column based on Search
            4. Find Counts for those Unique Values in Filtered Array

             

             

            When it iterates through the Search column to match the Unique Value, then a bunch of rows not in the Filtered by Date Array show up in that array and create an invalid count.  I hope that helps with the explanation.

            • 3. Re: ArrayCollection Filter creates ghost data
              LoganSix Level 1

              I created a function to actually get only those rows for the Date Range selected.

               

              public static function createDateFilteredArray(daSource:ArrayCollection):ArrayCollection {
                             var daLength:int = daSource.length;
                             var returnDArray:ArrayCollection = new ArrayCollection();
                             
                             for (var a:int = 0; a < daLength; a++){
                                  returnDArray.addItem(daSource.getItemAt(a));
                             }
                             
                             return returnDArray;
                        }
              

               

              Apparently copying the filtered ArrayCollection opens up for the bug I was seeing.  Since the original values are still in the "source", a second filtering on that value had the unintended results.  Copying the Filtered ArrayCollection to another ArrayCollection keeps the source data, so this function totally removes that possiblity by only copy the objects over that have been filtered.

               

              Probably not the correct way to do this, but for what I need, it was necessary.

              • 4. Re: ArrayCollection Filter creates ghost data
                UbuntuPenguin Level 4

                Remeber, you don't have to work with ArrayCollections, the Array class has

                a bucket full of sorting and filtering capabilities to, you might even want to check out some of the other properties such as "match", and "every".