This is a variant of map which makes it easy to special-case the last item in the list.
# usage: special_last_map { block } $sentinel_variable, @list_of_value
+s;
# You should examine the value of the sentinel variable inside your co
+de block.
# It will be True for the last item in the list; False otherwise.
sub special_last_map(&\$@)
{
my $code = shift;
my $is_last_sr = shift;
my $n = $#_;
map {
$$is_last_sr = $_ == $n;
local $_ = $_[$_];
&$code
} 0 .. $#_
}
For example, say you're stuffing a list of strings into an html list, and you want to add an attribute to the final <li> element:
my $is_last;
my @list_in_html =
special_last_map
{
my $attr = $is_last ? ' class="last"' : '';
"<li$attr>$_</li>"
}
$is_last,
@list;
Update: Ok, here's a version which makes checking for first and last items easy; and it uses $a and $b so that you don't have to provide any special variables.
sub map_with_index(&@)
{
my $code = shift;
my $n = $#_;
map {
local $a = $_;
local $b = $n - $_;
local $_ = $_[$_];
&$code
} 0 .. $#_
}
Example:
print for map_with_index
{
my $class = ( $a == 0 ? 'first' : '' ) . ( $b == 0 ? 'last' : ''
+);
my $attr = $class ? qq( class="$class") : '';
"<li$attr>$_</li>\n"
}
qw( alpha beta gamma delta );
What is the sound of Windows? Is it not the sound of a wall upon which people have smashed their heads... all the way through?