Thursday, October 07, 2010

A Simple Way to Compare Two Arrays in AS3

Here's a simple, understandable way in AS3 to take two arrays and extract the elements that are unique, or the elements that match.

It's always amazing to me how hard it is to find good, clear examples of this kind of thing on the internet. Maybe it's too elementary for the ActionScript 3 gurus to bother with. But since a quick search turned up nothing, and I ended up writing a couple of functions to do it, I figure I should share this for the next person that's looking.

Below are two functions. The first, findUnique, does the following when given two arrays:

  1. Make a temporary copy of the first array.
  2. Loop through the first array and on each element, loop through the second array to see if there is at least one match.
  3. When a match is found, delete the matching element from the temp copy and stop the nested loop.
  4. After the main loop is done, only unique values are left in the temp copy. Send that back.

The second, findMatches, does this when given two arrays:

  1. Make a temporary empty array.
  2. Loop through the first array, and on each element loop through the second array.
  3. When a match is found, add the matching element to the empty array and stop the nested loop.
  4. After the main loop is done, the empty array has all of the elements in the first array that are also found at least once in the second array. Send that back.

Here's the code:

package {
    import flash.display.*;
   
    public class arrayCompareTest extends MovieClip {

        private var array1:Array = new Array(1, 2, 9, 2, 4, 5, 6, 9, 2, 10); //base array
        private var array2:Array = new Array(2, 2, 4, 9, 11); //remove these

        public function arrayCompareTest():void {
            trace("uniques: "+findUnique(array1, array2)); //produces 1,5,6,10
            trace("matches: "+findMatches(array1, array2)); //produces 2,9,2,4,9,2
        }
       
        private function findUnique(arr1, arr2):Array{
            var justArr1:Array = arr1.slice(); //copy arr1. You can't use justArr1 = arr1, because that's a reference, not a copy, and you'll be deleting the non-uniques from here
            for(var i:int=arr1.length-1; i>-1; i--){ //iterate backwards, so changes to the order of things due to deletion happen behind the iteration
                for(var j:int=0; j<arr2.length; j++){ //this can iterate forward, because you're not deleting anything
                    if(arr1[i] == arr2[j]){ //loop through all of arr2 to see if there is at least one match
                        justArr1.splice(i,1); //delete the matching value from justArr1
                        break; //stop checking. If you don't stop, and there are more matches, the wrong things get deleted
                    }
                }
            }
            return(justArr1); //send the array back
        }
       
        private function findMatches(arr1, arr2):Array{
            var bothArr:Array = new Array(); //start with an empty array
            for(var i:int=0; i<arr1.length; i++){ //iterate through the first array
                for(var j:int=0; j<arr2.length; j++){ //iterate through the second array
                    if(arr1[i] == arr2[j]){ //loop through all of arr2 to see if there is a match
                        bothArr.push(arr1[i]); //add the matching value to the bothArr
                        break; //stop checking. If you don't stop, one copy will be added for every match in arr2, instead of a single copy
                    }
                }
            }
            return(bothArr); //send the array back
        }
    }
}


BTW, the code includes everything in the .as file, even the package, import, etc. I find it really annoying when people leave that stuff off. Sure, it's superfluous when you know what you're doing, but somewhere out there is someone learning this for the first time that doesn't know what they are doing. To them a complete example is invaluable.

Addendum: as3corelib and casalib are both great libraries full of useful classes and bits of code for mucking around with arrays, among other things. But neither one turned out to be very useful for this specific case.

2 comments:

Anonymous said...

Thanks.

[Gorjan]

Tiffany said...

As one of those people who is new to this and doesn't know what she's doing, I'm so grateful you posted the complete code here!