I feel like something is missing from the available minimum functions. I’ve come across the issue multiple times where i want to get the value of a collection that gives the minimum value of a specified function. i.e. I want to specify my own comparator.
min returns the smallest value in a collection (or the arguments). I assume comparison is done by isless. I guess I could overload isless but that seems heavy-handed for a one-time minimisation.
minimum also finds the smallest value in a collection. It also provides a method minimum(f, itr) which returns the smallest result of calling f on itr. This is close, but it returns the minimum value of f, not the value of itr that gives the value of f
argmin returns the index of the smallest element, which is helpful, but again doesn’t allow specifying a custom comparator.
So far I’ve been solving this with the below function, but this seems like it might be something that already exists elsewhere.
It seems like a missing feature: I think argmin(f, iter) and findmin(f, iter) should be defined. You can avoid the temporary allocation of map(f, itr) using MappedArrays, as suggested by @xiaodai.
You can also implement the function yourself, as it is quite straightforward (remember, your functions in Julia can be as fast as built-in ones).
There are some fun ways to achieve what you want, too:
reduce([-2, -1, 2, 3, 4]) do x, y
by = x -> x ^ 2
by(x) < by(y) ? x : y
end
although function by is executed more times than needed (which should be avoided if by is expensive).
Another way is:
minimum([-2, -1, 2, 3, 4]) do x
by = x -> x ^ 2
by(x), x
end[2]
this works because Tuples are compared lexicographically:
julia> (1, 2) < (2, 1)
true
In these examples I’m not considering the case when f(a) == f(b) for a ≠ b. Also, you may need to adapt these examples if you have special values such as NaN.