# How to find the index of the two largest values in a 1D array

Hi, I’m trying to find the index of the two largest values in an array.
I’ve been trying to work through find n smallest values in an n dims array but am getting confused because that is a 3D array.

This probably has a simple solution but it is evading me. I can’t use `findmax()` or `argmax()` since I don’t just want the largest value.

``````M = rand(6)

``````

``````julia> a = rand(6)
6-element Vector{Float64}:
0.1911141673445511
0.27806173115685107
0.37965238565322046
0.8664939772144525
0.5317414946847623
0.2850934557396858

julia> sortperm(a, rev=true)[1:2]
2-element Vector{Int64}:
4
5
``````

Edit: @DNF’s suggestion is to use `partialsortperm` … which is for sure better in this case. @fatteneder’s answer is apparently faster, and allocates less.

EDIT: Updated to return the indices of the two largest values and not their values.

If linear complexity is desired then just use a loop, because they are also fast in Julia:

``````function findlargest2(a::AbstractVector)
@assert length(a) >= 2
i1, i2 = 1, 2
max1, max2 = a[i1], a[i2]
if max1 < max2
max1, max2 = max2, max1
end
for i = 3:length(a)
ai = a[i]
if ai > max2
if ai > max1
i1, i2 = i, i1
max1, max2 = ai, max1
else
i2 = i
max2 = ai
end
end
end
return i1, i2
end
``````
``````julia> x = randn(8)
8-element Vector{Float64}:
0.8934664691033656
-1.5294590308293632
-0.13047453971043912
1.8016634206952808
-0.1771167975283893
2.097991657439888
-1.1881023747938395
-0.04860363743772466

julia> findlargest2(x)
(6, 4)
``````
2 Likes

It works, so thank you!. Why is `rev = true` (reverse sorting is performed)? If I make it false, the answer doesn’t make sense. Say the answer with `rev = true` is 4,2. I would expect the answer when `rev = false` to be 2,4 but the answer is 6, 5.

This will sort the entire array, which is a lot of unnecessary work. Instead, take a look at `partialsortperm`.

4 Likes

`rev` refers to the sorting order. If `rev=false` you will get the two smallest instead of the largest.

1 Like

using argmax(.)

``````
M = rand(6)

i1=argmax(M)

M[i1]=-Inf

i2=argmax(M)
``````

I believe that should be

``````    for i = 3:length(a)
``````

But otherwise that is a very effective approach — non-allocating and significantly faster than `partialsortperm`.

1 Like

Indeed, thanks for spotting. I update my version above!