Recipe 5.3. Searching for Matching Elements in an Array


Problem

You want to find the first element in an array that matches a specified value.

Solution

Use a for statement to loop through an array and a break statement once a match has been found. Optionally, use the ArrayUtilities.findMatchIndex( ), ArrayUtilities.findLastMatchIndex( ), and/or ArrayUtilities.findMatchIndices( ) methods.

Discussion

When you search for the first element in an array that matches a specified value, you should use a for statement, as shown in Recipe 5.2, and add a break statement to exit the loop once the match has been found.

Using a break statement within a for statement causes the loop to exit once it is encountered. You should place the break statement within an if statement so it is executed only when a certain condition is met.

When searching for the first matching element, the importance of the break statement is twofold. First, you don't need to loop through the remaining elements of an array once the match has been found; that would waste processing time. In the following example, the break statement exits the loop after the second iteration, saving six more needless iterations. (Imagine the savings if there were a thousand more elements!)

Furthermore, the break statement is vital when searching for the first match because it ensures that only the first element is matched and that subsequent matches are ignored. If the break statement is omitted in the following exampleall matching elements are displayed, as opposed to the first one only.

// Create an array with eight elements. var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];       // Specify what we want to search for. var match:String = "b";       // Use a for statement to loop through, potentially,  // all the elements of the array. for (var i:int = 0; i < letters.length; i++) {           // Check whether the current element matches      // the search value.     if (letters[i] == match) {               // Do something with the matching element.         // In this example, display a message          // for testing purposes.         trace("Element with index " + i +                " found to match " + match);               // Include a break statement to exit the for loop         // once a match has been found.         break;     }   }

You can also search for the last matching element of an array by reversing the order in which the for statement loops through the array. Initialize the index variable to Array .length -1 and loop until it reaches 0 by decrementing the index variable, as follows.

var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];       var match:String = "b";       // Loop backward through the array. In this example,  // the "b" is at index 5. for (var i:int = letters.length - 1; i >= 0; i--) {     if (letters[i] == match) {         trace("Element with index " + i +                " found to match " + match);         break;     }   }

To simplify the process of searching for matching elements, you can use some of the static methods of the custom ArrayUtilities class. The class is in the ascb.util package, so the first step is to import the class:

import ascb.util.ArrayUtilities;

The ArrayUtilities class has three methods for finding matching elements findMatchIndex( ), findLastMatchIndex( ), and findMatchIndices( ). The findMatchIndex( ) method requires at least two parameters: a reference to the array you are searching, and the value you want to match. The method then returns either the index of the first matching element or -1 if no matches are found; for example:

var letters:Array = ["a", "b", "c", "d"]; trace(ArrayUtilities.findMatchIndex(letters, "b")); // Displays: 1 trace(ArrayUtilities.findMatchIndex(letters, "r")); // Displays: -1

You can also specify the starting index from which the search begins. That way, you can find matches subsequent to the first match. Specify the starting index as the third parameter; for example:

var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"]; trace(ArrayUtilities.findMatchIndex(letters, "a", 1)); // Displays: 4

You can tell the method to find elements that are partial matches as well. By default, only exact matches are found. However, if you specify a value of TRue for the third parameter, the method finds any element containing the substring:

var words:Array = ["bicycle", "baseball", "mat", "board"]; trace(ArrayUtilities.findMatchIndex(words, "s", true)); // Displays: 1

If you want to run a partial match and still specify a starting index, simply pass the starting index as the fourth parameter.

The findLastMatchIndex( ) method works identically to findMatchIndex( ) except that it starts looking from the end of the array.

The findMatchIndices( ) method returns an array of indices for all elements that match the value passed in. The method requires at least two parametersthe array and the element you want to match. For example:

var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"]; trace(ArrayUtilities.findMatchIndices(letters, "b")); // Displays: 1,5

You can also run partial matches using findMatchIndices( ). Simply specify a Boolean value of true as the third parameter:

var words:Array = ["bicycle", "baseball", "mat", "board"]; trace(ArrayUtilities.findMatchIndices(words, "b", true)); // Displays: 0,1,3

Each of the ArrayUtilities methods described use the same basic techniques with a for statement. Let's take a look at the code for the methods. The findMatchIndex( ) method is fairly straightforward, and you can see the comments inline. One thing to note, however, is that the method doesn't use any break statements within the for loop. That's because it uses return statements if a match is found. In the context of a function or method, a return statement exits the for statement, so the break statement is not necessary:

public static function findMatchIndex(array:Array, element:Object):int {     // Use a variable to determine the index      // from which to start. Use a default value of 0.     var startingIndex:int = 0;     // By default don't allow a partial match.     var partialMatch:Boolean = false;     // If the third parameter is a number,      // assign it to nStartingIndex.     // Otherwise, if the fourth parameter is a number,     // assign it to nStartingIndex instead.     if(typeof arguments[2] == "number") {         startingIndex = arguments[2];     }         else if(typeof arguments[3] == "number") {         startingIndex = arguments[3];     }     // If the third parameter is a Boolean value,      // assign it to partialMatch.     if(typeof arguments[2] == "boolean") {         partialMatch = arguments[2];     }     // Assume no match is found.     var match:Boolean = false;     // Loop through each of the elements of the array      // starting at the specified starting index.     for(var i:int = startingIndex;             i < array.length; i++) {         // Check to see if the element either matches          // or partially matches.         if(partialMatch) {             match = (array[i].indexOf(element) != -1);         }         else {             match = (array[i] == element);         }         // If the element matches, return the index.         if(match) {           return i;         }     }     // The following return statement is only reached     // if no match was found. In that case, return -1.     return -1; }

The findLastMatchIndex( ) method is almost identical to the findMatchIndex( ) method, except that it loops in reverse. The findMatchedIndices( ) method loops through the array to find every matching index. It appends each matching index to an array, and then it returns that array. It uses the findMatchIndex( ) method, as shown here:

public static function findMatchIndices(array:Array,  element:Object, partialMatch:Boolean = false):Array {     var indices:Array = new Array(  );     var index:int = findMatchIndex(array,                                     element,                                    partialMatch);     while(index != -1) {         indices.push(index);         index = findMatchIndex(array,                                element,                                partialMatch,                                index + 1);     }     return indices; }

See Also

Recipes 5.2 and 5.10




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net