Removing duplicate items from an array using the Array.filter() method

I’m sure there is an easier/better way to do this (and I’ll update this post accordingly if I find one) but here is a little sample which takes an array of items and filters out the duplicates.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/05/removing-duplicate-items-from-an-array-using-the-arrayfilter-method/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init()">

    <mx:Script>
        <![CDATA[
            private var keys:Object = {};

            /**
             * Called by the Application container's creationComplete
             * event handler. This method creates a new Array object
             * which will be used as a data provider as well as a
             * filtered view of that array which does not contain
             * duplicated items.
             */
            private function init():void {
                /* Create a dummy data source with some semi-random
                    data. */
                var arr:Array = [];
                arr.push({data:1, label:"one"});
                arr.push({data:1, label:"one"});
                arr.push({data:1, label:"one"});
                arr.push({data:1, label:"one"});
                arr.push({data:2, label:"two"});
                arr.push({data:2, label:"two"});
                arr.push({data:2, label:"two"});
                arr.push({data:1, label:"one"});
                arr.push({data:3, label:"three"});
                arr.push({data:3, label:"three"});

                /* Filter the original array and call the
                    removeDuplicates() function on each item
                    in the array. */
                var filteredArr:Array = arr.filter(removedDuplicates);

                arrColl.source = arr;
                dedupedArrColl.source = filteredArr;
            }

            /**
             * This method is used to filter an array so that no
             * duplicate items are created. It works by first
             * checking to see if a keys object already contains
             * a key equal to the current value of the item.data
             * value. If the key already exists, the  current item
             * will not be readded to the data provider. If the key
             * does not already exist, add the key to the keys
             * object and add this item to the data provider.
             */
            private function removedDuplicates(item:Object, idx:uint, arr:Array):Boolean {
                if (keys.hasOwnProperty(item.data)) {
                    /* If the keys Object already has this property,
                        return false and discard this item. */
                    return false;
                } else {
                    /* Else the keys Object does *NOT* already have
                        this key, so add this item to the new data
                        provider. */
                    keys[item.data] = item;
                    return true;
                }
            }
        ]]>
    </mx:Script>

    <mx:ArrayCollection id="arrColl" />
    <mx:ArrayCollection id="dedupedArrColl" />

    <mx:HBox>
        <mx:VBox>
            <mx:Label text="Original ({arrColl.length} items):" />
            <mx:List dataProvider="{arrColl}" />
        </mx:VBox>
        <mx:VBox>
            <mx:Label text="Filtered ({dedupedArrColl.length} items):" />
            <mx:List dataProvider="{dedupedArrColl}" />
        </mx:VBox>
    </mx:HBox>

</mx:Application>

View source is enabled in the following example.

10 thoughts on “Removing duplicate items from an array using the Array.filter() method

  1. Bob,

    I believe it can.

    Try something like this:

    dedupedArrColl = new ArrayCollection(arr);
    dedupedArrColl.filterFunction = removedDuplicates;
    dedupedArrColl.refresh();
    

    And then change the filtering function to this:

    /** Note that the method has 1 parameter now instead of 3, the rest of the code can remain the same */
    private function removedDuplicates(item:Object):Boolean {
       // ...
    }
    
  2. Bob,
    let’s say you have an ArrayCollection AC with Strings S.
    To make sure that each String is represented only once:

    S=”Bob”;
    if ( !AC.contains(S)) AC.addItem(S);

  3. If you wanna use the filter function twice, you might wanna clear the keys object since it already has old values for second use.

    Snippet:

    keys={};
    var filterRoutes:Array = routesArray.filter(removedDuplicates);
    keys={};
    var filterDivisions:Array = divisionsArray.filter(removedDuplicates);

  4. when I use above filter function for ArrayCollection along with Datagrid, upon click of sort functionality, datagrid is becoming empty.
    how to resolve this issue?

  5. if I have 2 datagrids using the same array bindable. and I want the filter to be applied to only one of the datagrids. how?

Comments are closed.