[Function] Min/Max including with Associative Arrays

Post your working scripts, libraries and tools
FanaticGuru
Posts: 844
Joined: 30 Sep 2013, 22:25

[Function] Min/Max including with Associative Arrays

04 Dec 2017, 14:46

[Function] Min / Max

I have had a Min/Max function in my library for years that used a variadic parameter so that you could pass it as many parameters as you liked. This allowed it to also work with a simple array parameter if followed by a * but I discovered today that it did not work for associative arrays so I made a small tweak.

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus

Credits to Helgef.

The Min function requires Unicode encoding of the file as it uses a special extended character.

If that is a problem this ANSI encoding function can be used.

Code: [Select all] [Download] (Untitled.ahk)GeSHi © Codebox Plus

Min(List*)
{
List._NewEnum().Next(,X)
for key, element in List
if (element < X)
X := element
return X
}
This uses the _NewEnum().Next to get the starting value for comparison in an associative array which makes this function slower than the one above.

Examples of usage:

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus

Important to realize that alpha characters are greater than numbers.

Even thought Min/Max functions are fairly simple I figured these were worth posting as the ability to find the Min or Max value in an array is a pretty common need. These are also the fastest functions I could find that handled all the cases these functions can handle.

There can be 1 or more parameters that can be literals, variables, simple arrays, or associative arrays.

FG
Last edited by FanaticGuru on 11 Dec 2017, 14:17, edited 1 time in total.
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

Google Search, Dictionary, Thesaurus - Quickly Get Information from Specific Web Resources

[Function] Timer - Create and Manage Timers
Helgef
Posts: 2606
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Function] Min/Max including with Associative Arrays

04 Dec 2017, 18:43

Thanks for sharing FanaticGuru. :thumbup:
The ability to find the Min or Max value in an array is a pretty common need.

Ragnar has submitted a suggestion for built-in functions :arrow: github :thumbup:. It doesn't include string compairison but is variadic.

This gave me an idea for a new puzzle :arrow: Code Puzzle Thread (Puzzle 8).

Cheers.
FanaticGuru
Posts: 844
Joined: 30 Sep 2013, 22:25

Re: [Function] Min/Max including with Associative Arrays

11 Dec 2017, 14:32

Updated: 2017 12 11

Improved the performance of the functions in first post with the help of Helgef.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

Google Search, Dictionary, Thesaurus - Quickly Get Information from Specific Web Resources

[Function] Timer - Create and Manage Timers
Helgef
Posts: 2606
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Function] Min/Max including with Associative Arrays

12 Dec 2017, 06:58

Hello FanaticGuru.
I have a few comments. I realised, that there is less than ideal behaviour of the Min(X:="?", List*) if you pass Min([]*) :(. The Max version is ok.
Also, I haven't really used the feature of variadic calls in other cases than with linear arrays, that is, [x,y,...] rather than {keyX:valX, keyY:valY,...}. The documentation says
•Numbering of parameters within the source array begins at 1.

So it seems we miss numeric keys < 1 when we expand AssociativeArray* :o, example,

Code: [Select all] [Download] GeSHi © Codebox Plus

Min({0:1, 1:2}*) ; 2 :(

In v1, this is OK Min({"0":1, 1:2}*), but not in v2. Hence, for associative arrays, to be certain, one would need to pass the array rather than expand* it. Alternative function definition could be, Min(List) and the either call it like Min(array) if you have an array from the beginning, or Min([var1,var2]) if you want to pass variables. Or use multiple functions depending on the situation. Slightly sad.

Cheers.
FanaticGuru
Posts: 844
Joined: 30 Sep 2013, 22:25

Re: [Function] Min/Max including with Associative Arrays

12 Dec 2017, 17:58

Helgef wrote:In v1, this is OK Min({"0":1, 1:2}*), but not in v2. Hence, for associative arrays, to be certain, one would need to pass the array rather than expand* it. Alternative function definition could be, Min(List) and the either call it like Min(array) if you have an array from the beginning, or Min([var1,var2]) if you want to pass variables. Or use multiple functions depending on the situation. Slightly sad.

Yes, it appears associative arrays with numerical keys less than 1 are a problem.

Here is an attempt at a function that can handle this case as wells as allowing the mixing of all kinds of data structures.

Code: [Select all] [Expand] [Download] (Untitled.ahk)GeSHi © Codebox Plus

It is relatively quick when passing an array but when just sending two numbers it is going to be slower. Any improvements or comments are appreciated.

I am thinking in my library I will have:
Min that works great except with associative arrays with numerical keys less than 1.
MinArray that expects an array and handles as quickly as possible.
MinX that can handle a mix but might not be as quick as the two above.

Who would have thought a versatile and quick Min function would be so complicated.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

Google Search, Dictionary, Thesaurus - Quickly Get Information from Specific Web Resources

[Function] Timer - Create and Manage Timers
Helgef
Posts: 2606
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Function] Min/Max including with Associative Arrays

13 Dec 2017, 06:21

I am thinking in my library I will have:
It seems like this is what one has to do :think: .
Who would have thought a versatile and quick Min function would be so complicated.
Not me, thank you for bringing it up :ugeek: .

Note, Byref doesn't do anything with variadic parameters as far as I know.

Cheers.
User avatar
jeeswg
Posts: 3351
Joined: 19 Dec 2016, 01:58
Location: UK

Re: [Function] Min/Max including with Associative Arrays

13 Dec 2017, 06:40

- Which functions in AHK v1/v2, currently receive arrays? Is it just StrSplit? (Note: some functions accept arrays passed with *, but that's not what I'm interested in here.)
- With StrSplit, when you specify multiple delimiters via an array, it appears to check all numeric keys (including zero/negative integers), but not string keys.
- I think that generally it's better to ignore string keys, and perhaps better to only check positive integer keys. You just have to state that that's how the function works. I.e. at present, for general functions e.g. mathematical functions, I would generally write functions that only check positive integer keys. For object functions I would/wouldn't support all keys, depending on the situation, sometimes I might make two versions for linear/associative arrays. Also, sometimes I might make two functions to handle recursion or not.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



When you pass an object to a variadic function, the variance function appears to retrieve all of the keys, except for non-positive integer keys, which is interesting behaviour. So you get curious results if you do a for loop, however, if you use a loop based on oParams.Length(), you get the behaviour that I would hope to get.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


[EDIT:] I have added to the variadic functions code a little bit.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: gregster and 9 guests