in reply to Re^2: How to get the index of smallest whole number in an array?
in thread How to get the index of smallest whole number in an array?

Now that you mention it I agree with you, though I have not realised it earlier. Sorting is an overkill when just min value is required. But hey we cover every angle in our homework service :)

In which case your List::Util::reduce solution or a basic min-find will suffice:

$idx = $arr[0]; for(0..$#arr) { $idx = $_ if( ($arr[$idx]<0) || (($arr[$_] >= 0) && ($ +arr[$_] < $arr[$idx])) ) }

Replies are listed 'Best First'.
Re^4: How to get the index of smallest whole number in an array?
by AnomalousMonk (Archbishop) on Jul 02, 2018 at 22:46 UTC
    $idx = $arr[0]; for(0..$#arr) { $idx = $_ if( ($arr[$idx]<0) || (($arr[$_] >= 0) && ($arr[$_] +< $arr[$idx])) ) }

    This returns strange results for certain corner cases:

    c:\@Work\Perl\monks>perl -wMstrict -le "use Data::Dump qw(pp); ;; for my $ar ( [ ], [ -1 ], [ -99 ], [ 0, -99 ], [ -99, 0 ], ) { my $idx = $ar->[0]; for (0..$#$ar) { $idx = $_ if( ($ar->[$idx]<0) || (($ar->[$_] >= 0) && ($ar->[$_] +< $ar->[$idx])) ); } print qq{(@$ar) -> lnn index of }, pp $idx; } " () -> lnn index of undef (-1) -> lnn index of 0 Use of uninitialized value in numeric lt (<) at -e line 1. (-99) -> lnn index of -99 (0 -99) -> lnn index of 0 Use of uninitialized value in numeric lt (<) at -e line 1. Use of uninitialized value in numeric lt (<) at -e line 1. Use of uninitialized value in numeric lt (<) at -e line 1. (-99 0) -> lnn index of -99
    I'd hate to have to extend this to dealing with fractional numbers. The O(n) solutions here and here both return an unambiguous undef for lists containing no LNN, including empty lists.


    Give a man a fish:  <%-{-{-{-<

      Sure! I have somehow missed the O(n) solution you provided very early on. Had I seen it, I would have referred to it as it is more complete than my sketch.

Re^4: How to get the index of smallest whole number in an array?
by Veltro (Hermit) on Jul 03, 2018 at 18:29 UTC

    I have voted only for your solution. Because while everyone is showing solutions with sort, map grep. I just don't understand that after 30 posts finally someone is talking some sense.

    If I would have needed to solve something like this, I would have come up with a simple loop. Job done, move on:

    use strict ; use warnings ; my @arr = ( 3, 4, 71, 1, 1.5, -598, -100203, 0.5, -2, -1.5 ); my $result ; while (my ($ix, $val) = each @arr) { next if ( $val < 0 || int $val != $val || ($result && $val > $resu +lt->[0]) ) ; $result = [ $val, $ix ] ; } if ( $result ) { print $result->[0] . " at " . $result->[1] . "\n" ; } __END__ 1 at 3

      Congratulations: Another O(n) solution! Please note that the each ARRAY syntax is only available from Perl version 5.12 onward.


      Give a man a fish:  <%-{-{-{-<