Page 1 of 1

Ini read and output the Key name that has largest amount

Posted: 27 Nov 2017, 02:54
by HIAC
Hey people!
I would like to get "C" because it has the largest value in "INFO" selection.. How can I do that?
I would note that values are continuously changing

[INFO]
A=1
B=3
C=5
[INFOB]
D=20

Re: Ini read and output the Key name that has largest amount

Posted: 27 Nov 2017, 03:32
by gregster
IniRead can read a specific section and deliver a linefeed (`n) delimited list. I would loop-parse that list into single lines and apply StrSplit with a '=' delimiter to each line, leaving me with pairs of a letter and a number, of which I would look for that one with the highest number. And repeat...

Re: Ini read and output the Key name that has largest amount  Topic is solved

Posted: 27 Nov 2017, 07:04
by Odlanir

Code: Select all

IniRead, allSect, myIni.ini, INFO
maxValue := 0
loop, parse, allSect, `n
{
   RegExMatch(a_loopfield, "O)(.*)=(.*)",v)
   if ( v[2] > maxValue ) 
      maxValue := v[2], key := v[1]
}
MsgBox % "The key " key "`nHolds the max value : " maxValue

Re: Ini read and output the Key name that has largest amount

Posted: 27 Nov 2017, 07:07
by HIAC
Thanks a lot! :D

Re: Ini read and output the Key name that has largest amount

Posted: 27 Nov 2017, 09:42
by A_AhkUser
Hi HIAC,

If you expect only positive integers, this also can be achieved in-line:

Code: Select all

IniRead, pairs, % iniFile, INFO
MsgBox % (Object(StrSplit("0`n" . pairs . "`n", ["=", "`n"])*)).maxIndex()
[EDIT]
Looks like I misread the title... in order to retrieve the key name instead, and without using RegExMatch:

Code: Select all

IniRead, pairs, ini.ini, INFO
max := (Object(StrSplit("0=" . (pairs:=StrReplace(pairs, "`n", "=")) . "=", "=")*)).maxIndex()
str := SubStr(pairs, 1, InStr(pairs, "=" . max . "=") - 1)
MsgBox % SubStr(str, InStr(str, "=", false, 0) + 1)

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 14:49
by HIAC
@A_AhkUser Thanks.

@Odlanir, is it possible to output last 3 with max value?

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 16:17
by jeeswg
@A_AhkUser: This is nice, a nice hack that you've done to get the maximum number in a list. Here's a version done on a comma-separated list instead of some ini data.

WARNING: Both these scripts are out of interest, they are not general methods, and can only handle integers (and where: max >= 0).

Code: Select all

q:: ;number list get maximum
;1,3,5 -> 1,,3,,5, -> {1:"",3:"",5:""}
;5 is MaxIndex, 5 is Length

vText := "1,3,5"
oArray := Object(StrSplit(StrReplace(vText, ",", ",,") ",")*)
MsgBox, % oArray.MaxIndex()

;one-liner:
MsgBox, % Object(StrSplit(StrReplace(vText, ",", ",,") ",")*).MaxIndex()
return
[EDIT:] Here's a version done on ini data.

Code: Select all

q:: ;ini data get maximum value
;a=1,c=3,e=5 -> a,1,c,3,e,5 -> 0,a,1,c,3,e,5, -> {0:"a",1:"c",3:"e",5:""}
vText := "
(
a=1
c=3
e=5
)"
oArray := Object(StrSplit("0," vText ",", [",","="])*)
MsgBox, % oArray.MaxIndex()
return

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 16:21
by HIAC
Could you kindly make me one like you did previously to read .ini file but outputting last 3 instead :))

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 16:53
by A_AhkUser
Hi HIAC,

Using the method above (btw I edit my first reply which was wrong):

Code: Select all

IniRead, pairs, ini.ini, INFO
o := Object(StrSplit("0`n" . pairs . "`n", ["=", "`n"])*)
maxToRetieve := 3
Loop % maxToRetieve {
var%a_index% := o.maxIndex()
o.removeAt(o.MaxIndex())
}
MsgBox % var1
MsgBox % var2
MsgBox % var3
[EDIT]
Note: again, this will work only if you expect only positive integers.
@A_AhkUser: This is nice, a nice hack that you've done to get the maximum number in a list. Here's a version done on a comma-separated list instead of some ini data.
Thanks jeeswg. Btw it relies on THE hack of Helgef to convert ini data to an object

[EDIT]

And in order to retrieve the key names...

Code: Select all

IniRead, pairs, ini.ini, INFO
pairs := "0=" . StrReplace(pairs, "`n", "=") . "="
o := Object(StrSplit(pairs, "=")*)
maxToRetieve := 3
Loop % maxToRetieve {
MsgBox % SubStr(pairs, InStr(pairs, (str:="=" . o.maxIndex() . "=")) - 1, 1)
o.removeAt(o.MaxIndex())
}

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 17:01
by HIAC
Thank you, how can i divide them in 3 different variables?

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 17:46
by A_AhkUser
HIAC wrote:Thank you, how can i divide them in 3 different variables?

You can use for example a pseudo-array (I edited my last post with an example of a pseudi-array and also once again added an example which retrieve key names instead...)

Re: Ini read and output the Key name that has largest amount

Posted: 01 Dec 2017, 18:32
by HIAC
Thanks a lot! It works, but there is another problem -.-

A=30.000000
B=15
C=5
D=8
E=11.800000
F=1

it won't consider numbers with decimals in it, so result would be 15, 8,5 instead of 30,11,15

Re: Ini read and output the Key name that has largest amount

Posted: 02 Dec 2017, 11:33
by A_AhkUser
HIAC wrote:it won't consider numbers with decimals in it, so result would be 15, 8,5 instead of 30,11,15
That's what I said. Here's a more general solution:

Code: Select all

maxToRetieve := 3
IniRead, sections, ini.ini, INFO
o := {}, s := ""
Loop, parse, % sections, `n
	i := InStr(A_LoopField, "="), l := SubStr(A_LoopField, 1, i), m := SubStr(A_LoopField, i), o[m] := l, s .= m
var := LTrim(s, "=")
Sort, var, N D=
o := StrSplit(var, "=")
Loop % maxToRetieve {
MsgBox % o[o.length()]
o.pop()
}

Re: Ini read and output the Key name that has largest amount

Posted: 02 Dec 2017, 11:43
by A_AhkUser
A_AhkUser wrote:
HIAC wrote:it won't consider numbers with decimals in it, so result would be 15, 8,5 instead of 30,11,15
That's what I said. Here's a more general solution:

Code: Select all

maxToRetieve := 3
IniRead, sections, ini.ini, INFO
o := {}, s := ""
Loop, parse, % sections, `n
{
	i := InStr(A_LoopField, "=") ; what's the position of '='  in the current field ('A_LoopField') from 'sections' retrieved by parsing it using `n as delimiter ?
	l := SubStr(A_LoopField, 1, i) ; left part
	m := SubStr(A_LoopField, i) ; right part
	o[m] := l ; key and value are reversed: one can use the value to retrieve the key later
	s .= m ; appends '=value' to 's'
}
var := LTrim(s, "=") ; remove the trailing '=' from the begining of 's'
Sort, var, N D= ; sort 'var' numerically using = as delimiter
o := StrSplit(var, "=") ; creates an array by splitting var using '=' as delimiter
Loop % maxToRetieve
	MsgBox % o.pop() ; removes and returns the last array element.

[EDIT] Added comments

Re: Ini read and output the Key name that has largest amount

Posted: 02 Dec 2017, 21:07
by jeeswg
Here are two other ideas:

Code: Select all

q::
vText := " ;continuation section
(
A=30.000000
B=15
C=5
D=8
E=11.800000
F=1
)"
Sort, vText, F SortPairAsc
MsgBox, % vText
return

SortPairAsc(vText1, vText2, vOffset) ;for use with AHK's Sort command
{
	vNum1 := RegExReplace(vText1, ".*=")
	vNum2 := RegExReplace(vText2, ".*=")
	return vNum1 < vNum2 ? 1 : vNum1 > vNum2 ? -1 : -vOffset
}

w::
vText := " ;continuation section
(
A=30.000000
B=15
C=5
D=8
E=11.800000
F=1
)"

oArray := []
Loop, Parse, vText, `n, `r
{
	oTemp := StrSplit(A_LoopField, "=")

	;Objects
	;https://autohotkey.com/docs/Objects.htm
	;AHK x32 supports -2147483648 to 2147483647

	;negative so that the bigger numbers
	;appear first in an object loop
	vNum := Round(-oTemp.2*1000000)
	if !oArray.HasKey(vNum)
		oArray[vNum] := []
	oArray[vNum].Push(A_LoopField)
}

vOutput := ""
for vKey in oArray
	for vKey2, vValue in oArray[vKey]
		vOutput .= vValue "`r`n"
MsgBox, % vOutput
return

Re: Ini read and output the Key name that has largest amount

Posted: 03 Dec 2017, 07:30
by Helgef
Hello :wave:
For the slightly off-topic sorting of ini-values,
A_AhkUser wrote:If you expect only positive integers, this also can be achieved in-line:
For all real numbers, v2,

Code: Select all

sort(regexreplace(section, "m)(^.+=\s{0,})(.+$)", "$2"), "N")
For v1,

Code: Select all

sortIniSectionValues(section, opt:="N"){
	section:=regexreplace(section, "`am)(^.*=\s{0,})(.*$)", "$2")	; removes keyX = 
	sort section, % opt
	return section
}
note that the `a option is not needed in v2.

Cheers.

Re: Ini read and output the Key name that has largest amount

Posted: 04 Dec 2017, 05:33
by HIAC
Thanks everyone.

@A_AhkUser

This is what I need, but just if I could output the Key name too! I saw the code you posted, but I'm just too new so I don't get it :(

Code: Select all

IniRead, pairs, ini.ini, INFO
o := Object(StrSplit("0`n" . pairs . "`n", ["=", "`n"])*)
maxToRetieve := 3
Loop % maxToRetieve {
var%a_index% := o.maxIndex()
o.removeAt(o.MaxIndex())
}
MsgBox % var1
MsgBox % var2
MsgBox % var3