Home > OS >  How to get the index of the maximum element in an array?
How to get the index of the maximum element in an array?

Time:08-08

I want to find the maximum value in an array and print his index.

I wrote this for print the maximum value; it works but I don't know how print the index.

use feature "say";
use List::Util qw(max);
@x=qw(10 -2 -48 -5 7 34 28);
say "valore massimo: ".max @x;

CodePudding user response:

List::UtilsBy provides the max_by, for getting a maximum according to some other criterion (which could be another list).

use 5.010;
use List::UtilsBy qw/max_by/;

my @x = qw(10 -2 -48 -5 7 34 28);
my @indices = (0..@x-1);
say max_by { $x[$_] } @indices;

Generally, if you're doing nontrivial list manipulation in Perl, I recommend installing List::AllUtils, which is an all-in-one package including List::Util, List::SomeUtils, and List::UtilsBy.

CodePudding user response:

The core List::Util comes with an almighty reduce, which can be used to direclty work out all kind of results

use warnings;
use strict;
use feature 'say';

use List::Util qw(reduce);

my @x = qw(10 -2 -48 -5 7 34 28);

my $max_idx = reduce { $x[$a] > $x[$b] ? $a : $b } 0..$#x;

say "Maximal value of $x[$max_idx] is at index $max_idx";

Many libraries for list utilities handily package single expressions using reduce.

A utility with the above functionality is max_by from List::UtilsBy, as shown in Silvio Mayolo's answer (but we don't have to make an array of indices first).


A nitpick but I 'd like to offer my view. The list of (obviously) numbers given in the question as qw(10 -2 -48 -5 7 34 28) is a list of strings ("words"), as qw operator builds things.

These will be treated as (converted to) numbers as they are used as such and all is well, as is done regularly by the interpreter. However, since they are clearly to be numbers I prefer to introduce them as such,

my @x = (10, -2, -48, -5, 7, 34, 28);

A touch more typing but I find that it conveys the intent more clearly. Again, by all means this is of no consequence for most (any?) code.

CodePudding user response:

The task you are doing is absolutely basic and crucial to programming. If you start to learn programming, you should be able to come up with a solution on your own.

Yes, there exists nice modules that make this task a lot more elegant, but if you are learning to programming, you should come up at least with a solution like this, ON YOUR OWN!

printf "%d\n", max_index(10,3,22,5,4,11,33); # prints 6
printf "%s\n", max_index(34,21,100,12,9);    # prints 2

sub max_index {
    my ( @list ) = @_;
    
    my $max_index = 0;
    my $max_value = shift @list;
    
    my $idx = 0;
    for my $current ( @list ) {
        $idx  ;
        if ( $current > $max_value ) {
            $max_index = $idx;
            $max_value = $current;
        }
    }
    
    return $max_index;
}

Homework:

  1. What happens if you pass no element to the function? What should be returned?
  2. Make it work with an array reference.
  3. Use a classic for-loop for (..., ..., ...) { ... }, and don't use shift.
  4. What happens if you pass strings to it, instead of numbers?
  5. Do you know a solution to problem 4?

CodePudding user response:

In situation if you would prefer to use only Perl due restriction on Perl module installation - to find index of maximum value in an array you could use following algorithm:

  • assume that first element in the array has $max value
  • compare following array elements with $max
  • store index and value for max element if satisfices the condition
use strict;
use warnings;
use feature 'say';

my @arr = qw(10 -2 -48 -5 7 34 28);
my($ind,$max) = find_max(\@arr);

say "arr[$ind] = $max";

sub find_max {
    my $arr = shift;

    my($i,$max)=(0,$arr->[0]);
    
    for( 1..$#{$arr} ) {
        ($i,$max) = ($_,$arr->[$_]) if $max < $arr->[$_];
    }
    
    return ($i,$max);
}

Output

arr[5] = 34
  • Related