tye suggested that minima be added to List::Util. It looks something like this. Of course, his minima was probably terser/cleaner :)
sub minima(&@) {
my $value = shift(@_);
my @matches;
my $min_val;
{
local $_ = shift(@_);
$min_val = &$value();
@matches = $_;
}
foreach (@_) {
my $val = &$value();
if ($val == $min_val) { push(@matches, $_); }
elsif ($val < $min_val) { $min_val = $val; @matches = $_; }
}
return @matches;
}
If so, the original question can be solved with:
use List::Util qw( minima maxstr );
my $val = maxstr
minima { length }
@list;
and the bonus question can be solved with:
use List::Util qw( minima );
sub pick { $_[rand(@_)] }
my $val = pick
minima { length }
@list;