in reply to Efficiently finding values of an extremity

I think ikegami's solution is fine; but I thought it would be nice if one could use the exact same comparison function that one would pass to sort. So that if you'd say
sort { length($a) <=> length($b) or $a cmp $b } @data;
to get the entire data set in the desired order, you could simply s/sort/minima/ to get only the minima from that set:
minima { length($a) <=> length($b) or $a cmp $b } @data;
Here's how:
sub minima(&@) { my $comp = shift; @_ <= 1 and return(@_); my @cur = ( $_[0] ); for my $i ( 1 .. $#_ ) { local( $a, $b ) = ( $cur[0], $_[$i] ); my $r = &$comp; if ( $r > 0 ) { @cur = ($_[$i]); } elsif ( $r == 0 ) { push @cur, $_[$i]; } # else keep current best. } @cur }

However, this doesn't address the third requirement, I'm not really sure what is wanted there. Does it need to be truly random? Or is it that we simply don't care which one we get? If the latter, then one can simply take the first from the resulting list. If the former, then one could apply F-Y to the resulting list. Either way, it's outside the scope of concern of this function, I think.

Replies are listed 'Best First'.
Re^2: Efficiently finding values of an extremity (WTDI)
by tye (Sage) on Jul 20, 2005 at 19:29 UTC

    I like that way of slicing it as well, but I think the name 'minima' fits it less well than it fits my way of slicing it. It is nice that yours only requires a single routine rather than 4 flavors. (I also like that mine uses a simpler key-generating function.)

    I'd call it "firsts" but I was already told that would be confusing since there is already List::Util::first. Perhaps "leaders"?

    - tye        

      Yeah, I was originally inclined to call it "first". "firsts" is even better. But how about "optima"?