views:

3888

answers:

7

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?

+3  A: 

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

Boon
A: 
myMovieClip.name == "foo";

^== if you want to assign a variable, use

myMovieClip.name = "foo";
Unreality
Not really an answer, eh?
musicfreak
The original question, "Both indexOf() above do not work", but I'm stating the bug that caused the indexOf failed
Unreality
+3  A: 

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

back2dos
A: 

Hello:

When I move elements or positions inside Array of Objects I lost his propertys.

I need move Objects that are inside the array, have listeners......

Thanks for all

+1  A: 

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"));
Virusescu
A: 

Here is what I did. Change the function name if you want... this is all just for the sake of explanation.

getObjectFromArrayByProperty(arrayToSearch, 'oBjectProperty', 'value');

function getObjectFromArrayByPoperty(array:Array, _property, search:String):Object{
    for (var i:int = 0; i < array.length; i++) {
     if (array[i][_property] == search) {
       return array[i];
     }
    }
    return null;
}

This returns the object instead of just an index. If a match is not found, the function returns null.

topherez
A: 

Virusescu, elegant solution. Made me feel down-right stupid for not thinking of it myself. :)

AnthMan