Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

array.max() / array.min()


  • Please log in to reply
24 replies to this topic
infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
I've been using min() and max() user functions all over the place. (like these, and the ones needed in this function)

Mine uses a variadic param and loops through it, however Lexikos has suggested alternate method of passing a single array instead. Really, six one way, half a dozen another.

However I think it would be actually useful to have built in ObjMax() and ObjMin() that return the maximum and minimum values (not indexes) of an object and can be accessible with array-dot notation like: [1,2,3,"abc"].max()

Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010
On a partially related note, I'd also like to see ObjCount() to get the count of objects not using integer keys...

Yes, I'd like to see ObjMin() and friends built in too.

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
I like the idea of ObjCount() / myobject.count() to give the count of all keys, not just integer keys.

fincs
  • Moderators
  • 1662 posts
  • Last active:
  • Joined: 05 May 2007
+1

Iggy_
  • Members
  • 90 posts
  • Last active: Nov 16 2012 05:55 PM
  • Joined: 29 May 2011
Min() and Max() would be handy, Count() even more so, even if just for arrays.

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
+1

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
I would like to see real-world examples of where these functions would be useful, especially since we're missing other functions which I think would be more commonly used (such as IndexOf/Find). How often does one need to know the number of non-numeric keys?

tidbit
  • Administrators
  • 2709 posts
  • Hates playing Janitor
  • Last active: Jan 15 2016 11:37 PM
  • Joined: 09 Mar 2008
just last week I needed the count of all array items. though the script no longer exists....

on the other hand, who would just need the count numeric keys? what about only the string cheese (sorry, couldn't resist.)?

why just limit the users to numbers?

rawr. be very afraid
*poke*
. Populate the AutoHotkey city. Pointless but somewhat fun. .


infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
How about initializing a binary variable to put pointers from each element in an object into just before a for k,v in obj which gets both numeric and non-numeric keys.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

why just limit the users to numbers?

Along the same line of thought, why not limit the users to numbers?

All of the practical uses I've had for knowing the number of items in an array have been with items numbered 1..N, and knowing N was more important than knowing the actual number of items in the array (when there may be extra information stored as string key-value pairs which aren't supposed to be part of the array data).

How about initializing a binary variable to put pointers from each element in an object ...

Without sufficient context, I cannot consider that a real-world example.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I tend to agree with Lexikos that an integrated IndexOf() function would be more important.

If one wants to extend on this, something in the direction of query syntax like LINQ in C# would be very nice. Or maybe even just supporting finding the index of an object that has a key with a specific value.

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
Hmm, I think IndexOf() / Find() for objects is important but I also think that ObjCount() is more generically important.

There have been several times when it would have been nice to have the count of non-numeric keys, which could be found by: obj.count() - (obj.maxindex() OR 0) (v2) as long as there are actually maxindex() numeric keys.

Along those lines, ObjCount() would give essential information about objects with sparsely populated numeric keys: {10: "abc", 100: "def", 1000: "ghi", 10000: "jkl"}

One sees throughout the forums loop % obj.maxindex() (me included) which in the case of the object above, would make the code iterate 9996 more times than necessary, not only being detrimental to performance but also possibly yielding crazy results because all those keys that don't exist would unexpectedly be blank. ObjCount() would give us a tool to find these cases and code around them.

Uberi
  • Moderators
  • 1119 posts
  • Last active: May 02 2015 06:05 PM
  • Joined: 23 Aug 2010
In most cases it is possible to use ObjGetCapacity() to get the number of keys, but when an object is explicitly resized using ObjSetCapacity() scripts may fail. In my tests objects automatically expand just enough to hold the additional keys added but I am not sure about larger objects, and depending on this behavior is probably not very forward compatible.

Are sizes stored in objects? If so, ObjCount() potentially has a large performance benefit over creating an enumeration and iterating through it.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

In most cases it is possible to use ObjGetCapacity() to get the number of keys, but when an object is explicitly resized using ObjSetCapacity() scripts may fail.

On the contrary - if you don't shrink the object to its minimum required capacity (i.e. the number of valid key-value pairs) first, there's likely to be excess. Objects usually start with a capacity of 4 and double in capacity each time more is needed, but this can vary depending on how the object is populated.

... and depending on this behavior is probably not very forward compatible.

SetCapacity: "If less than the current number of key-value pairs, the object is shrunk to fit." So if you do SetCapacity(0) then GetCapacity(), you should be safe.

Are sizes stored in objects?

Yes, which also means that Count() would be very simple.

ObjCount() would give us a tool to find these cases and code around them.

OTOH, it would be easier to just use a for-loop in the first place. I generally only use Loop % obj.MaxIndex() when I'm aware that either there are non-numeric keys I want to avoid, or the array is sparsely populated but I still want to iterate once per possible index (not per actual index).


Enough about Count(). What about Min() and Max()?

Searching for a value: Considering how MinIndex() and MaxIndex() define an "index", IndexOf() might be inappropriate. I might go with KeyOf(), since Find() is a bit too generic. However, "KeyOf" seems a bit unconventional. I did some searching, and PHP's array_search() was the only equivalent function I could find, although I found a few languages with methods like ContainsValue(). :?

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008
Old topic, I know.

For a search function, I like "Contains". It's similar to ahk B/L's if var contains convention and would bring similar functionality to v2 where all non-expression if's have been removed.

I'm currently using these for Min() and Max() as standalone functions. They allow both syntaxes: min/max of arg values AND min/max of object values. I.e. if only one arg is passed and the one arg is an object, then it returns the max value of the object.

min(n, x*) {
    if ObjMaxIndex(x) == 0 && IsObject(n)
        x := n, x._NewEnum().next(k,n)
    for k,v in x
        if (v < n)
            n := v
    return n
}

max(n, x*) {
    if ObjMaxIndex(x) == 0 && IsObject(n)
        x := n, x._NewEnum().next(k,n)
    for k,v in x
        if (v > n)
            n := v
    return n
}

I'm sure if they were built-in they would be significantly faster, but perhaps this or something similar could be included in the stdlib.