# Is there any way to use max() and min() based on a function?

This is easily done in, for example, Python, and can be very useful. I have spent quite a bit of time searching documentation and reading forum questions, without finding anything.

Here’s a small example of what I would like to do:

``````arr = [1,2,3,4,-5]
sqmax = max(arr, by = x -> x^2)
``````

I know this can be done as follows, but it seems like it would make sense for max() to have a `by` option.

``````sqmax = sort(arr, by = x -> x^2)[end]
``````

You are looking for what is called `maximum` in Julia. Take a look at the documentation on `max` and `maximum` for more examples.

Welcome to the forum. A question like this is better suited for the “Usage” category.

3 Likes

But still there is no built in `maxiumum` function offering whats requested.

I’d go with:
`findmax(map(x->x^2,arr))`

Update: this is only needed if you want the index, which I initially thought was asked.

`maximum` does take an optional function as its first argument. Try `maximum(x -> x^2, arr)`.

6 Likes

why not:

``````maximum(arr.^2)
``````

The problem with that is that it creates a temporary array, which can be avoided by passing the function as an argument.

3 Likes

That allocates an intermediate array for the squared array whereas the version from simon does not. It would be nice if we could reduce over a broadcasted array without allocs one day but we’re not there yet.

thanks for the answer, but `maximum(f, arr)` will return the maximal element in `f(arr)` rather than in `arr`.
Is there any keyword of `maximum` or other functons to “find x in arr s.t. f(x) is maximal”

Example:

``````xs = [1, 3, 2]; i = argmax([x^2 for x in xs]); println(xs[i])
``````

You can also pass the function to argmax, to avoid the allocation of the intermediate array:

``````julia> x = [1,3,2]
3-element Vector{Int64}:
1
3
2

julia> argmax(x -> -x^2, x)
1

julia> argmax(x -> x^2, x)
3

``````
4 Likes
``````julia> findmax(abs2, -3:2)
(9, 1)
``````

the second returned value can be used to index the `arr`

or just use:

``````julia> argmax(abs2, -3:2)
-3
``````

which does the `indexing` for you under the hood

3 Likes
``````foldl((x,y)->x^2>y^2 ? x : y, arr)
``````

or

``````foldl((x,y)->ifelse(x^2>y^2 , x , y), arr)
``````
``````maxby(f,arr)=foldl((x,y)->f(x)>f(y) ? x : y, arr)
``````
1 Like

Yes, for those wondering, this feature was added in Julia v1.7. Quite useful/convenient on occasion.

Open issue up for grabs: Add a `by` keyword to `maximum` and `minimum` · Issue #28210 · JuliaLang/julia · GitHub

(Of course, you could just write your own loop for this, which is perfectly fast.)

1 Like

Thanks! I found out this implementation is new in Julia 1.7. For 1.6 or lower version, it still can be done by a less direct way

``````data[argmax(f.data)]
``````