The Pearls of Raku, Issue 8: the secrets of min (and max)
source link: https://andrewshitov.com/2020/08/23/the-pearls-of-raku-issue-8-the-secrets-of-min-and-max/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
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.
Table of Contents
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; # <strong>Inf</strong>
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
.
* * *
Find the code of this issue on GitHub and browse for more Raku Pearls.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK