Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

index of the minimum element of the array

by Anonymous Monk
on Jan 17, 2014 at 13:10 UTC ( [id://1070950]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

hi, i got an array, f. e. @a = (1, 5, 7, 9); i need to find the minimum element of the array and return it's index. i tried this: use List::Util qw( min max ); my $min = min @a; but it doesn't work for some reason. is there another way?
  • Comment on index of the minimum element of the array

Replies are listed 'Best First'.
Re: index of the minimum element of the array
by LanX (Saint) on Jan 17, 2014 at 13:42 UTC
    Neither List::Util nor List::MoreUtils export a function returning the minimums index only the minimal value.

    If you don't like the classical way of a for loop checking the min and memorizing the last index you can try combining min with first_index. (note that's inefficient)

    HTH! =)

    update

    Or do you want a sub minindex ?

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      yeah, a sub for minindex would be good. atm i am unable to patch perl on current pc, so a busrouitine for index would be the best solution for me.
        What did you try?

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        Also take a look at List::Util for some basic examples.

        use List::Util 'reduce'; sub minindex { reduce { $_[$a] < $_[$b] ? $a : $b } 0 .. $#_ }

        Update: Less succinct now when fixed:

        use List::Util 'reduce'; sub minindex { my @x=@_; reduce { $x[$a] < $x[$b] ? $a : $b } 0..$#_ }

Re: index of the minimum element of the array
by davido (Cardinal) on Jan 17, 2014 at 16:06 UTC

    The "classical way" is to set up a variable for $min, and a variable for $min_index, then to iterate through your array by index, and any time the element at a given index is less than $min, set $min equal to that element, and $min_index equal to the current index. At the end of the loop, $min_index will contain the correct value. In Perl, undef is less than any defined value, so you don't strictly need to deal with explicitly populating $min on the first iteration, or doing a definedness check, but you will get some warnings if you don't test definedness first.

    That's the classical method; the one taught to beginning programmers almost regardless of which language they're using as the means of learning programming. And it's probably the method you've discussed in class. If the class discussion was inadequate, a little searching might have turned up How can I find the index of the biggest element in an array?, which provided some good solutions which can be adapted to find the minimum instead pretty easily. Here's one based on GrandFather's answer in that thread:

    my @array = ( 1, 5, 7, 9 ); sub minindex { my( $aref, $idx_min ) = ( shift, 0 ); $aref->[$idx_min] < $aref->[$_] or $idx_min = $_ for 1 .. $#{$aref}; return $idx_min; } print minindex(\@array), "\n";

    Dave

Re: index of the minimum element of the array
by hippo (Bishop) on Jan 17, 2014 at 13:49 UTC

    It may not have an index (at least not a scalar one). Consider the list: (2, 5, 2, 7) - what is the index of the minimum value here?

Re: index of the minimum element of the array
by ikegami (Patriarch) on Jan 17, 2014 at 18:14 UTC
    use List::Util qw( reduce ); sub min_idx { my ($ar) = @_; return reduce { $ar->[$b] > $ar->[$a] ? $b : $a } 0..$#$ar; }
    which is equivalent to the cheaper
    sub min_idx { my ($ar) = @_; return undef if !@$ar; my $idx = 0; for (1..$#$ar) { $idx = $_ if $arr->[$_] > $arr->[$idx]; } return $idx; }

    Usage:

    my $min_idx = min_index(\@a);
Re: index of the minimum element of the array
by InfiniteSilence (Curate) on Jan 17, 2014 at 14:20 UTC

    Here's one way

    perl -e 'use List::Util qw|min|; $pos = 0; @a = qw|95 41 3 9 2|; %ha +shPos = map {$_=>$pos++} @a; print $hashPos{scalar min @a};' Prints 4

    Celebrate Intellectual Diversity

Re: index of the minimum element of the array
by ww (Archbishop) on Jan 17, 2014 at 13:42 UTC
    Works for me on a Win7 box with Perl 5.16 and the addition of an output command:
    C:\>perl -E "@a = (1, 5, 7, 9);use List::Util qw( min max ); my $min = + min @a;say $min;" 1

    But, note, using "a" (and "b") as variable names is bad practice because they are special to sort. If you get in the habbit of using a meaningful, multicharacter name -- @array or @arr or @ar in this kind of case -- a non-specific example -- you'll avoid puzzles in the future.

    NB also: You posted a dupe moments later. Don't. Register and you'll be able to edit if need be...

    /me reddens with embarassment: /me replied to the dupe (Substance up to "NB" was identicial) before noticing that it was a dupe.

    And even more chagrin: misread the OP, which clearly asks for "index" rather than value.

    Come, let us reason together: Spirit of the Monastery
Re: index of the minimum element of the array
by tangent (Parson) on Jan 17, 2014 at 13:45 UTC
Re: index of the minimum element of the array
by Not_a_Number (Prior) on Jan 17, 2014 at 19:18 UTC

    Use python:

    a = [1, 2, -17, 99] min_idx = a.index(min(a))

    Or ruby:

    a = [1, 2, -17, 99] min_idx = a.index(a.min)

    ;-)

    Update: Momentary confusion javascript/ruby. Corrected. Thanks, LanX.

    This is the JS example I intended to supply:

    var a = [1, 2, -17, 99]; var min_idx = a.indexOf(Math.min.apply(Math, a));

      OP said "atm i am unable to patch perl on current pc, so a busrouitine for index would be the best solution for me." Suggesting another language seems like it is well outside the realm of possibility here.

      If we are going to suggest alternatives that involve installing things, why leave Perl? PDL provides a simple solution which is far more efficient than any of your solutions from other languages:

      use PDL; my $index = pdl(@data)->minimum_ind;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1070950]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-19 17:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found