Jump to content

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

AHK_L - Contains/HasValue Method


  • Please log in to reply
4 replies to this topic
IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007
This is a request for AHK_L (1.1) as for AHK v2.
In AHK v2, probalby there will be more predefined Objects like "List" or "Collection" for this usage. For now, we just have one super general Object, which should provide easy usage.


We have a "HasKey" method, to check if a key is present. Whats about checking values? obj.HasValue/obj.Contains?

names := ["Peter","Max","Rob"]

if(names.Contains("Max")) ; or name it similary to HasKey:  HasValue
{
    msgbox Mr Max is here.
}

On a related note, standardized equality checks for Objects would be nice. (Necessary when the array contains Objects instead of flat values)
If a class/prototype has a Method defined called "Equals(other)" use it to determine instance equality. If it is not defined, fall back to reference equality check.

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

In AHK v2, probalby there will be more predefined Objects like "List" or "Collection" for this usage.

There may be an array type and an object type, but there was never any plan for more than that.

(Necessary when the array contains Objects instead of flat values)

I disagree - it's not necessary. It makes sense to use reference equality, the same as =/==/!=, and key comparisons. Maybe it would be useful, but no more than overloading other operators. I suppose that it would make HasValue/Contains much slower when objects are present. If the array contains only objects, there mightn't be much difference between a built-in method calling Equals on each object and a user-defined method doing the same via a for-loop.

What do you think of returning the first key associated with the given value? Would the usage or name need to change? There would be ambiguity with 0 (false) or even "", but that seems trivial.

IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

I suppose that it would make HasValue/Contains much slower when objects are present.

If there are Objects, and if there is a Method "Equals" present in this Object (or any of its bases) it will of course cost more execution time. (Don't know how much the checking for the Method costs thought) But using a own for-loop, might be even a bigger performance hit.

But if you are after performance, the code should be designed anyway to look up Keys in the dictionary instead of values. :)

If the array contains only objects, there mightn't be much difference between a built-in method calling Equals on each object and a user-defined method doing the same via a for-loop.

It is just something, which I use in virtually any AHK project. Therefore, I expect that lots of other people also need to check for values in lists, it would just be a often used short-hand.
It makes also the code much more readable.

What do you think of returning the first key associated with the given value? Would the usage or name need to change?

+1
I think it would correspond to the mentality of AHK and we would be able to combine a "IndexOf/KeyOf" method with a Contains method. I think the name "HasValue" would fit well.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Sounds good. I would like to even propose two further methods to return the key/value of an object in an array/object which has a specific sub-key:
ActiveWin := Windows.GetObjectWithValue("hwnd", WinExist("A"))

I have used this kind of function very frequently so far.

trismarck
  • Members
  • 390 posts
  • Last active: Nov 25 2015 12:35 PM
  • Joined: 02 Dec 2010

I second the request for .HasValue(). .HasValue() could simplify the following code:

    if(a = b
     &&  c = d)
        for each, letter in alphabet
            if(letter = "q")
                return, true, ErrorLevel := 0

into:

if(a = b
 &&  c = d
 && alphabet.HasValue("q") )
    return, true, ErrorLevel := 0

//edit: or actually, I've realized I can write that function:

;{
; The function checks if the object has a given value.
;
;}
ObjHasValue(aObj, aValue) {
    for key, val in aObj
        if(val = aValue)
            return, true, ErrorLevel := 0
    return, false, errorlevel := 1
}

Not sure if it would be beneficial to add .HasValue() then.


Edited by trismarck, 12 January 2014 - 10:09 PM.

New Autohotkey forum: http://ahkscript.org.