Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AS3 - Is it possible to search an Array by Object properties?

Would it be possible to use Array.indexOf() to search through an Array by the properties of the Objects within the array:

var myArray:Array = new Array();
var myMovieClip = new MovieClip();

myMovieClip.name = "foo";

myArray.push(myMovieClip);
myArray.indexOf(MovieClip.name == "foo"); //0 

OR

myArray.indexOf(myMovieClip.name == "foo"); //0

Both indexOf() above do not work, is there away to achieve this with the correct syntax?

like image 922
RValentine Avatar asked Jun 01 '09 01:06

RValentine


3 Answers

Look into Array's filter method (newly available for AS3). You can write a filter method that returns all objects that will meet your criteria (in your case, a movieclip with a certain name)

like image 186
Boon Avatar answered Oct 13 '22 17:10

Boon


index of will search for an entry ... MovieClip.name == "foo" should throw a compiler error, since MovieClip does not have a property "name" ... myMovieClip.name == "foo" will be true, and then you will get the index of true, if it is in the array at all ...

if you really need the index, you will need to iterate over the array ... by key ... or in an incremental loop, if the array is numeric and dense ... if the array is associative (string keys used) you imperatively need to use for-in loops, since filter and related functions will only cover numeric indices ...

in a numeric array, i'd suggest one of the following two approaches:

//this will return an array of all indices
myArray.map(function (val:*,index:int,...rest):int { return (val.name == "foo") ? index : -1 }).filter(function (val:int,...rest):Boolean { return val != -1 });

//here a more reusable utility function ... you may want to put it to some better place ... just as an example ...
package {
     public class ArrayUtils {
          public static function indexOf(source:Array, filter:Function, startPos:int = 0):int {
               var len:int = source.length;
               for (var i:int = startPos; i < len; i++) 
                    if (filter(source[i],i,source)) return i;
               return -1;
          }
     }
}
//and now in your code:
var i:int = ArrayUtils.indexOf(myArray, function (val:*,...rest):Boolean { return val.name == "foo" });

hope that helped ... ;)

greetz

back2dos

like image 3
back2dos Avatar answered Oct 13 '22 16:10

back2dos


Though back2dos' method is cool, I think beginners might find it overly-complicated, so for the sake of them here is a simpler method, that may be easier to use, though won't be as versatile for any situation as back2dos' method.

var myArray:Array = new Array();
var myMovieClip1 = new MovieClip();
var myMovieClip2 = new MovieClip();

myMovieClip1.name = "foo";
myMovieClip2.name = "bar";

myArray.push(myMovieClip1);
myArray.push(myMovieClip2);

function getIndexByName(array:Array, search:String):int {
    // returns the index of an array where it finds an object with the given search value for it's name property (movieclips, sprites, or custom objects)
    for (var i:int = 0; i < array.length; i++) {
        if (array[i].name == search) {
            return i;
        }
    }
    return -1;
}

trace("bar index = "+getIndexByName(myArray, "bar"));
trace("foo index = "+getIndexByName(myArray, "foo"));
like image 2
Virusescu Avatar answered Oct 13 '22 17:10

Virusescu