0

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?

1
  • Since you're using arrays, I assume you're using Bash, is that correct? Commented Dec 10, 2018 at 18:20

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

You don't even need that assumption; for i in ${!arr[@]}; do. The rest of your code takes a little tweaking to avoid the assumption that 0 is the smallest index.
I'd just check arr[i] <= max once, and continue the loop if true. Then you can unconditionally update maxIdx and max.
@chepner But I wanted to use the ternary operator ;) Oh, I see you've removed your answer... I'll update this one again.
1

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

Comments

1
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.

Comments

0

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
$

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.