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.

 
Tagged with:
 
About The Author

Peter deHaan

Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.

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

  1. FlexLover says:

    Tank’you very much, this is the right example for me.

  2. Bob says:

    Nice example! Can this be done with an ArrayCollection as well?

  3. peterd says:

    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 {
       // ...
    }
    
  4. Yuri says:

    Thanks, man! That’s what I needed here. Awesome!

  5. ixdl says:

    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);

  6. 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);

  7. priya says:

    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?

  8. Wagner says:

    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?

  9. HQ says:

    Very nice example! Thank you very much!