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;
}