In this issue, we’ll be focusing on the built-in min
function. Occasionally, also on max
, but the whole story is well applicable to both of them. Some of the elements can also be used with other functions.
How to use min
This is not a trivial question, actually 🙂 Let’s take an array with some integers, both positive and negative, and find the minimum value using different forms of the call:
my @data = 3, -2, 6, 1, 5; say min @data; # -2 say min(@data); # -2 say @data.min; # -2 say @data.min(); # -2
As you can see, both a standalone function and a method are available.
But that’s not it. You can use a reduction operator with the min
function in it:
say [min] @data; # -2
According to the definition, this is equivalent to the following chain, which you can also use (but why):
say @data[0] min @data[1] min @data[2] min @data[3] min @data[4]; # -2<
min
of nothing
What if you apply min
to an empty array? The result is logical but maybe not always intuitively straightforward.
my @a; say @a.min; # Inf
Indeed, if you want to find a minimum element in the loop, you usually start with the first element and compare the next element with it. If you start with infinity, you do not have to make any special use of the first element to warm up the loop.
The same happens to ()
, Empty
, Nil
, or Any
:
say ().min; # Inf say Empty.min; # Inf say Nil.min; # Inf say Any.min; # Inf
You can find more similar examples, but let me mention that with max
, you get -Inf
:
say @a.max; # -Inf say ().max; # -Inf say Empty.max; # -Inf say Nil.max; # -Inf say Any.max; # -Inf<
min
with by
The min
routine accepts the named argument :by
, which you can use to modify the value before the function actually makes the comparison. For example, with our initial data array, let us find the absolute minimum value:
my @data = 3, -2, 6, 1, 5; say min(@data, :by( { abs($_) } )); # 1
I added some air around the braces and parentheses for better visibility, but you can also use the WhateverCode
block to increase it further:
say min(@data, by => -*); # 6
In this example, all the elements are negated and min
serves as max
.
N.B.! In the case of using a method, the only optional argument &by
is a positional argument, so you can’t pass it as a named parameter. Just pass the code:
say @data.min({abs($_)}); # 1 say @data.min: {abs($_)}; # 1 say @data.min: -*; # 6
* * *
Find the code of this issue on GitHub and browse for more Raku Pearls.