8 Replies Latest reply on May 10, 2007 2:11 PM by michaeljbaird

    Like Values in an Array

    michaeljbaird
      Is there a way to sort out like values in an Array in Flex?

      Example:
      Before:
      [2,3,4,5,5,6,8,8,9,9,9,9]
      After:
      [2,3,4,5,6,8,9]
        • 1. Re: Like Values in an Array
          upshotvideo Level 1
          I'm not sure if there is a built in unique_array method, but you could build a pretty simple function to loop through the array and handle that by putting each array element into another array but checking first if it exists in your new array. Something like that?
          • 2. Like Values in an Array
            michaeljbaird Level 1
            OK something like this:

            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="filterArray();">
            <mx:Script>
            <![CDATA[
            [Bindable] private var newArray:Array = new Array;
            private function filterArray():void
            {
            for(var z:int=0;z<oldArray.length;z++)
            {
            var In:Boolean = false;

            if(newArray.length == 0)
            {
            newArray.push(oldArray[z]["num"]); //pushing first element if array has none
            continue;
            }

            for(var j:int=0;j<newArray.length;j++)
            {
            trace(newArray[j].toString() +"=="+ oldArray[z]["num"].toString());
            if(newArray[j] == oldArray[z]["num"]) //if there is that element in array, element is skipped
            {
            In = true;
            break;
            }
            }

            if(In == false) //if that element is not in array, it's pushed
            {
            newArray.push(oldArray[z]["num"]);
            }
            }

            newArray.sort(); //Sort Array Ascending
            cb.dataProvider = newArray; //Set ComboBox DataProvider
            }
            ]]>
            </mx:Script>
            <mx:Array id="oldArray">
            <mx:Object num="8"/>
            <mx:Object num="8"/>
            <mx:Object num="7"/>
            <mx:Object num="7"/>
            <mx:Object num="1"/>
            <mx:Object num="1"/>
            <mx:Object num="1"/>
            <mx:Object num="2"/>
            <mx:Object num="3"/>
            <mx:Object num="4"/>
            <mx:Object num="4"/>
            <mx:Object num="4"/>
            <mx:Object num="5"/>
            <mx:Object num="6"/>
            <mx:Object num="6"/>
            </mx:Array>
            <mx:ComboBox id="cb" labelField="num" horizontalCenter="0" verticalCenter="0" width="200">
            </mx:ComboBox>
            </mx:Application>





            Is there a cleaner....more simpler way?
            • 3. Re: Like Values in an Array
              ntsiii Level 3
              If you can always count on duplicates being together, I think you can make this more efficient. Look into "splice".

              Also, perhaps using an associative array to hold the unique results might work better. Its hash table behavior should be more efficient that looping every time.

              Tracy
              • 4. Re: Like Values in an Array
                michaeljbaird Level 1
                quote:

                Also, perhaps using an associative array to hold the unique results might work better. Its hash table behavior should be more efficient that looping every time.


                Could you show an example from what I've done above?
                • 5. Like Values in an Array
                  VarioPegged Level 2
                  As mentioned above, if like values are always going to be together (or if you're able to just sort the original array first), then use a somewhat simpler approach with a single for loop to check for duplicate values in the updated filterArray() function (see bolded lines) and you could assign the array literal in the init() function:

                  private var arr:Array;
                  [Bindable]
                  private var newArr:Array;

                  //could be called at creationComplete event
                  private function init():void
                  {
                  //initialize the original array
                  //guessing that you'll populate this array from some external data, not hard-coded
                  arr = [8,8,7,7,1,1,1,2,3,4,4,4,5,6,6];
                  filterArray();
                  }

                  private function filterArray():void
                  {
                  if ((newArr.length == 0) && (arr.length != 0)) { newArr.push(arr[0]); }

                  if (arr.length > 1)
                  {
                  //sort the original array to get the format we're expecting
                  arr.sort();
                  for (var n:int = 1; n<arr.length; n++)
                  {
                  if (arr[n] != arr[n - 1]) { newArr.push(arr[n]); }
                  }
                  }

                  newArr.sort(); //Sort Array Ascending - not necessary if you're able to sort original array above
                  cb.dataProvider = newArr; //Set ComboBox DataProvider
                  }

                  Edit: I've just noticed that you're using mxml mx:Array in your example. Is there a specific reason for doing this and not via Actionscript?
                  • 6. Re: Like Values in an Array
                    michaeljbaird Level 1
                    Thanks VarioPegged ,

                    I had to modify your code just slightly
                    newArrr:Array = new Array;
                    &
                    arr.sort(); has to be done before the conditonal or the 1 is missing from the new Array

                    I was just using mxml Array to test Associative Arrays obviously it could be done like this:
                    oldArray["num"] = [5,8,7,1,4,2,6,3,4,5,4,5,6,9];

                    My data source will actually be a column from a datagrid who's dataprovider is a webservice.



                    <?xml version="1.0" encoding="utf-8"?>
                    <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();">
                    <mx:Script>
                    <![CDATA[
                    [Bindable] private var newArr:Array = new Array;

                    private var arr:Array = [5,8,7,1,4,2,6,3,4,5,4,5,6,9];
                    //could be called at creationComplete event
                    private function init():void
                    {
                    //initialize the original array
                    //guessing that you'll populate this array from some external data, not hard-coded

                    filterArray();
                    }

                    private function filterArray():void
                    {
                    //sort the original array to get the format we're expecting
                    arr.sort();

                    if ((newArr.length == 0) && (arr.length != 0))
                    {
                    newArr.push(arr[0]);
                    }

                    if (arr.length > 1)
                    {
                    for (var n:int = 1; n<arr.length; n++)
                    {
                    if (arr[n] != arr[n - 1])
                    {
                    newArr.push(arr[n]);
                    }
                    }
                    }
                    newArr.sort(); //Sort Array Ascending - not necessary if you're able to sort original array above
                    cb.dataProvider = newArr; //Set ComboBox DataProvider
                    }
                    ]]>
                    </mx:Script>

                    <mx:ComboBox id="cb" labelField="num" horizontalCenter="0" verticalCenter="0" width="200"/>

                    </mx:Application>
                    • 7. Re: Like Values in an Array
                      VarioPegged Level 2
                      I had to modify your code just slightly
                      newArrr:Array = new Array;
                      &
                      arr.sort(); has to be done before the conditonal or the 1 is missing from the new Array


                      Oops, yeah, good catch. newArr should be instantiated and arr.sort() must be called first thing within the function. I usually try and run the code I provide on forums, but time is scarce...
                      The most reusable version of filterArray() would probably be to pass your old array to it as a parameter and stick the function into a Utils class of some sort.

                      The init() function the way you have it now is redundant then.
                      • 8. Re: Like Values in an Array
                        michaeljbaird Level 1
                        quote:

                        The most reusable version of filterArray() would probably be to pass your old array to it as a parameter and stick the function into a Utils class of some sort.


                        Funny you say that because that is exactly what I'm using it for. Then I can use the method anytime with any array! Thanks for the help!

                        filterArray(oldArray:Array, newArray:Array)