How to add to the key of a For-loop Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
magicinmath
Posts: 162
Joined: 12 Apr 2017, 23:03

How to add to the key of a For-loop

11 Oct 2017, 11:41

Wondering how you can add to the key such that the key increments more then +1 per round of the loop.

For example, if I wanted to msg box just the 1's in this object:

Code: Select all

object:=[1,0,0,1,0,0,1]
for a, v in object
{
    msgbox, %v%
    a:=a+2            ;  this doesnt actually change the key value
}
Such as achieved by this while loop:

Code: Select all

object:=[1,0,0,1,0,0,1]
a:=1
while(a<object.length()){
    a:=a+3
    msgbox, % object[a]
}
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to add to the key of a For-loop

11 Oct 2017, 12:26

That's just how for loops work in AHK, one key at a time, AFAIK.
2 workarounds, and an alternative using Loop, which is what I would probably do:

Code: Select all

q::
object := [1,0,0,1,0,0,1]
for a, v in object
{
	if (Mod(A_Index, 3) = 1)
		MsgBox, % v
}
return

;==================================================

w::
object := [1,0,0,1,0,0,1]
for a, v in object
{
	if (Mod(a, 3) = 1)
		MsgBox, % v
}
return

;==================================================

e::
object := [1,0,0,1,0,0,1]
Loop, % Ceil(object.Length() / 3)
{
	MsgBox, % object[A_Index*3-2]
}
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
magicinmath
Posts: 162
Joined: 12 Apr 2017, 23:03

Re: How to add to the key of a For-loop

11 Oct 2017, 21:46

Youi're sure? I'm not looking to do this in the context of the example, it was just a quick way to explain what I wanted. I run into a lot of loops like this with subarrays, I'm not sure these examples you give would be suited for but thanks for the info.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How to add to the key of a For-loop  Topic is solved

12 Oct 2017, 13:05

That is how the built-in enumerator works, you can define your own enumerator (also see for-loop and _newEnum()), taking any amount of steps per iteration, or do whatever you want. Simple example of a variable step-sized enumerator,

Code: Select all

class myStepEnum extends enumbase{
	__new(arr,stepSize:=3,startAt:=1){
		this.arr:=arr
		this.ss:=stepSize
		this.i:=startAt
	}
	next(byref key, byref value:=""){
		return objhaskey(this.arr,this.i) ? (value:=this.arr[this.i], key:=this.i, this.i+=this.ss, true) : false
	}
}
class enumbase {
	next(byref key:="", byref value:=""){
		throw exception("Next() not implemented.")
	}
	_newenum(){
		return this
	}
}
Example usage,

Code: Select all

myArray:=[0,0,1,0,0,2,0,0,3]
stepSize:=3
startAt:=3
for k, v in new myStepEnum(myArray,stepSize,startAt)
	str.= k "`t" v "`n" 
msgbox % str:="key:`tval:`n" . str
/*
key:	val:
3		1
6		2
9		3
*/
Another example, just to feed your imagination,

Code: Select all

arr:=[0,37,1,0,0,2,37,0,3]
arr["hello"]:=37
for k, v in new enumByVal(arr,37)
	str.= k "`t" v "`n" 
msgbox % str:="key:`tval:`n" . str
/*
key:	val:
2		37
7		37
hello	37
*/
class enumByVal extends enumbase {
	; Loop visits only key/value pairs where value = val
	__new(arr,val){
		this.arr:=arr
		this.enum:=arr._NewEnum()
		this.val:=val
	}
	next(byref k:="", byref v:=""){
		while this.enum.next(k,v){
			if (v=this.val)
				return true
		}
		return false
	}
}
Cheers.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Joey5, just me and 216 guests