ArrchanaMohan
ArrchanaMohan

Reputation: 2566

How to find the max value in array without using sort cmd in shell script

I have a array=(4,2,8,9,1,0) and I don't want to sort the array to find the highest number in the array because I need to get the index value of the highest number as it is, so I can use it for further reference.

Expected output:

 9 index value => 3

Can somebody help me to achieve this?

Upvotes: 0

Views: 448

Answers (4)

Benjamin W.
Benjamin W.

Reputation: 52112

Slight variation with a loop using the ternary conditional operator and no assumptions about range of values:

arr=(4 2 8 9 1 0)
max=${arr[0]}
maxIdx=0

for ((i = 1; i < ${#arr[@]}; ++i)); do
    maxIdx=$((arr[i] > max ? i : maxIdx))
    max=$((arr[i] > max ? arr[i] : max))
done

printf '%s index => values %s\n' "$maxIdx" "$max"

The only assumption is that array indices are contiguous. If they aren't, it becomes a little more complex:

arr=([1]=4 [3]=2 [5]=8 [7]=9 [9]=1 [11]=0)
indices=("${!arr[@]}")
maxIdx=${indices[0]}
max=${arr[maxIdx]}

for i in "${indices[@]:1}"; do
    ((arr[i] <= max)) && continue
    maxIdx=$i
    max=${arr[i]}
done

printf '%s index => values %s\n' "$maxIdx" "$max"

This first gets the indices into a separate array and sets the initial maximum to the value corresponding to the first index; then, it iterates over the indices, skipping the first one (the :1 notation), checks if the current element is a new maximum, and if it is, stores the index and the maximum.

Upvotes: 2

stack0114106
stack0114106

Reputation: 8711

Using Perl

$ export data=4,2,8,9,1,0
$ echo $data | perl -ne ' map{$i++; if($_>$x) {$x=$_;$id=$i} } split(","); print "max=$x", " index=",--${id},"\n" '
max=9 index=3
$

Upvotes: 0

anubhava
anubhava

Reputation: 785058

Without using sort, you can use a simple loop in shell. Here is a sample bash code:

#!/usr/bin/env bash

array=(4 2 8 9 1 0)

for i in "${!array[@]}"; do
   [[ -z $max ]] || (( ${array[i]} > $max )) && { max="${array[i]}"; maxind=$i; }
done

echo "max=$max, maxind=$maxind"

max=9, maxind=3

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 140960

arr=(4 2 8 9 1 0)
paste <(printf "%s\n" "${arr[@]}") <(seq 0 $((${#arr[@]} - 1)) ) | 
sort -k1,1 | 
tail -n1 |
sed 's/\t/ index value => /'
  1. Print each array element on a newline with printf
  2. Print array indexes with seq
  3. Join both streams using paste
  4. Numerically sort the lines using the first fields (ie. array value) sort
  5. Print the last line tail -n1
  6. The array value and result is separated by a tab. Substitute tab with the output string you want using sed. One could use ex. cut -d, -f2 to get only the index or use read a b <( ... ) to read the numbers into variables, etc.

Upvotes: 1

Related Questions