use List::Util 'max'; my $largest_val = max map { expensive_func($_) } @items; #### my $largest_item = argmax { expensive_func($_) } @items; #### my ($largest_item, $largest_val) = argmax { expensive_func($_) } @items; #### sub argmax(&@) { my $index = undef; my $max = undef; my $block = shift; for (@_) { my $val = $block->($_); if ( not defined $max or $val > $max ) { $max = $val; $index = $_; } } return wantarray ? ($index, $max) : $index; } sub argmin(&@) { my $index = undef; my $min = undef; my $block = shift; for (@_) { my $val = $block->($_); if ( not defined $min or $val < $min ) { $min = $val; $index = $_; } } return wantarray ? ($index, $min) : $index; }