5.6. Applying a Bit of IndirectionSome problems that may appear very complex are actually simple once you've seen a solution or two. For example, suppose you want to find the items in a list that have odd digit sums but don't want the items themselves. What you want to know is where they occurred in the original list. All that's required is a bit of indirection.[25]
First, you have a selection problem, so you use a grep. Let's not grep the values themselves but the index for each item:
Here, the expression 0..$#input_numbers will be a list of indices for the array. Inside the block, $_ is a small integer, from 0 to 6 (seven items total). Now, you don't want to decide whether $_ has an odd digit sum. You want to know whether the array element at that index has an odd digit sum. Instead of using $_ to get the number of interest, use $input_numbers[$_]:
The result will be the indices at which 1, 16, and 32 appear in the list: 0, 4, and 5. You could use these indices in an array slice to get the original values again: my @odd_digit_sums = @input_numbers[ @indices_of_odd_digit_sums ]; The strategy here for an indirect grep or map is to think of the $_ values as identifying a particular item of interest, such as the key in a hash or the index of an array, and then use that identification within the block or expression to access the actual values. Here's another example: select the elements of @x that are larger than the corresponding value in @y. Again, you'll use the indices of @x as your $_ items:
In the grep, $_ varies from 0 to the highest index of @x. If that element is beyond the end of @y, you automatically select it. Otherwise, you look at the individual corresponding values of the two arrays, selecting only the ones that meet your match. However, this is a bit more verbose than it needs to be. You could simply return the boolean expression rather than a separate 1 or 0:
More easily, you can skip the step of building the intermediate array by simply returning the items of interest with a map:
If the index is good, return the resulting array value. If the index is bad, return an empty list, making that item disappear.
Copyright © 2003 O'Reilly & Associates. All rights reserved. |
|