Page 1 of 1

objects: get correct case key name

Posted: 10 May 2017, 17:17
by jeeswg
This code shows how to get the correct case version of a key name. Is there a more direct method?

Code: Select all

q::
oArray := {}
oArray["KeY"] := "value"
for vKey in oArray
	if (vKey = "key")
		MsgBox, % vKey
oArray := ""
return
[EDIT:] E.g. if you use an array for a spellchecker, and you want to check if the key is lowercase/title case/uppercase/mixed case. If retrieving the case of the key is too slow, then perhaps you would include that information within the key's value, or use Scripting.Dictionary.Exists() (however, would checking for the existence of 4 keys be slower) etc. I will do some benchmark tests.

Re: objects: get correct case key name

Posted: 11 May 2017, 09:55
by IMEime
The array key treats "cat" same as "Cat/cAt/CAT".

Re: objects: get correct case key name

Posted: 11 May 2017, 11:28
by Guest
Convert it to a hex encoded string and use that as the key? Or similarly, hash the key?

Re: objects: get correct case key name

Posted: 11 May 2017, 19:33
by Helgef
Guest wrote:Convert it to a hex encoded string and use that as the key? Or similarly, hash the key?
Good idea :thumbup:
Try this,

Code: Select all

q::
oArray := new csa
oArray["KeY"] := "value1"
oArray["Key"] := "value2"
oArray["KEy"] := "value3"

msgbox, % oArray["KeY"]
msgbox, % oArray["Key"]
msgbox, % oArray["KEy"]
for k, v in oArray
	msgbox, % k  " " v
oArray := ""
return

class csa {
	__new(cap:=0){
		objrawset(this,"a",[])
		if cap
			this.a.setcapacity(cap)
	}
	__set(k,v){
		return this.a[this.ordKey(k)]:=v
	}
	__get(k){
		return this.a[this.ordKey(k)]
	}
	ordKey(k){
		for i, ch in strsplit(k)
			key.=ord(ch) . "|"
		return key
	}
	keyOrd(k){
		for i, o in strsplit(k,"|")
			key.=chr(o)
		return key
	}
	_newenum(){
		return new csa.csaEnum(this.a.newenum())
	}
	class csaEnum{
		__new(e){
			this.e:=e
		}
		next(byref k, byref v){
			r:=this.e.next(k,v)
			k:=csa.keyOrd(k)
			return r
		}
	}
}

Re: objects: get correct case key name

Posted: 12 May 2017, 03:22
by IMEime
캡처1.JPG
캡처1.JPG (13.82 KiB) Viewed 1718 times
When the speed matters, it's a nonsense(exactly 5 times slower).
Or, it's just OK.

Code: Select all

Count := 20000
Ary := {}
vTickCount1 := A_TickCount
Loop % Count
	Ary["MyKey" A_Index] := "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"
result_Ary := A_TickCount - vTickCount1
Dict := ComObjCreate("Scripting.Dictionary")
vTickCount1 := A_TickCount
Loop % Count
	Dict.item("MyKey" A_Index) := "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"
result_Dic := A_TickCount - vTickCount1
Obj := new csa
vTickCount1 := A_TickCount
Loop % Count
	Obj["MyKey" A_Index] := "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz"
result_Obj := A_TickCount - vTickCount1
MsgBox % ""
.	"Array : " result_Ary "`n"
.	"Object : " result_Obj "`n"
.	"Dictionary : " result_Dic "`n"
Return

Re: objects: get correct case key name

Posted: 12 May 2017, 15:32
by Helgef
@IMEime, I'm not sure I get your point, imo, In the context of of spellchecking, you are probably not going to be concerned if adding 20000 values to an array takes 47 ms or 245 ms.
@jeeswg, I don't really get the point of case when spell checking. What does the keys in your array represent?
Pseudo-code guess,

Code: Select all

a:={mispell:misspell}
if a[word]
	replace(word,a[word])
About storing case in value, that is a good approach to finding a case-key-value pair, :thumbup:

Code: Select all

ary:=[]
ary["key"]:=[["key","val1"],["Key","val2"],["kEy","val3"]]
for k, pair in ary["key"]
	Msgbox, % pair[1] " " pair[2]
Cheers.

Re: objects: get correct case key name

Posted: 12 May 2017, 15:49
by jeeswg
I really like that arrays within a key approach, it's quite interesting, something I might want to use one day, I'll keep it in mind ...

Usually I use a case-insensitive spellchecker. However, if you wanted a case-sensitive spellchecker, I would probably do the following:

time=L
Greenwich=T
UTC=U (or perhaps UTC=X)
FormatTime=X

'time' can be lowercase or title case or uppercase
'Greenwich' can be title case or uppercase
'UTC' can be uppercase only (it must have the case 'UTC')
'FormatTime' must have the case 'FormatTime'

However you don't really need values, the case of the word by itself, would imply L/T/U/X.

HasKey is sufficient for a case-insensitive spellchecker. Now what I would like to do, rather than simply HasKey, HasKey and then return the key in its original case, and then determine the case of the key's name, lower/title/upper/special, and then that will determine whether the word being spellchecked matches the word, that it has an appropriate case for that word e.g. 'utc' and 'Utc' would not be acceptable. The keys would be empty, with no value.

Now in this case, I might as well just specify values for the keys, rather than not have values and try to retrieve the case of the keys. However, if it were easy, there might be advantages to being able to retrieve the case of a key's name directly.

Re: objects: get correct case key name

Posted: 12 May 2017, 17:37
by Helgef
I see, makes sense.