Ada, ALGOL, BASIC, C, C++, C#, DWScript, F#, Go, Java, Logo, OCaml, Pascal, Perl, PicoLisp, PureBasic, Seed7, Tcl, and more use For to step through a sequence like -6 to 6
D has foreach()
Forth omits uses do after the fact ("7 -6 do")
Fortran and REXX use Do
Python uses for with range()
Ruby uses do like this: "-6.upto(6) do |h|"
Sather has .upto
Smalltalk uses to: and do: ("-6 to: 6 do: [ :h |]")
(that's a lotta' langs!)
AutoHotkey stands out from all of these, having no provision for this type of loop. Instead, we initialize a counter and use a While loop.
I don't know how hard it would be to code, but Loop already does this with A_Index and 1 to loop's param.
I would like either a keyword Do or for For to be extended :wink:

Traditional For loop (i.e., step through a sequence)
Started by
nimda
, Sep 10 2011 02:59 AM
18 replies to this topic
#1
-
Posted 10 September 2011 - 02:59 AM

This is easily solved via a function, which generates a range on the fly.
(Should I post this function in the Scripts & Functions sub-forum?)
Edit: Updated the code and made optional parameter to required one. There was some problems... keep it simple.
Or you reverse the objects keys with values, so the value is index and the keyname is range value. In this case For k in range(1, 4) is enough, no ignoring of second value.
#NoEnv SendMode Input SetWorkingDir %A_ScriptDir% For k,v in range(3, 5) MsgBox %v% For k,v in range(1, 4) MsgBox %v% s := "" For k, v in range(-3, 6) s .= k "=" v "`n" MsgBox % s s := "" For k, v in range(3, -6) s .= k "=" v "`n" MsgBox % s range(from, to) { range := {} if (from < to) While, (from <= to) range[A_Index] := from++ else While, (from >= to) range[A_Index] := from-- return range }Usage is easy, just ignore the k part (which is A_LoopIndex) and use the second variable. Not exactly the same as in Python, but close.
(Should I post this function in the Scripts & Functions sub-forum?)
Edit: Updated the code and made optional parameter to required one. There was some problems... keep it simple.
Or you reverse the objects keys with values, so the value is index and the keyname is range value. In this case For k in range(1, 4) is enough, no ignoring of second value.
#NoEnv SendMode Input SetWorkingDir %A_ScriptDir% For k in range(3, 5) MsgBox %k% For k,v in range(1, 4) MsgBox %k% s := "" For k, v in range(-3, 6) s .= k "=" v "`n" MsgBox % s s := "" For k, v in range(3, -6) s .= k "=" v "`n" MsgBox % s range(from, to) { range := {} if (from < to) While, (from <= to) range[from++] := A_Index else While, (from >= to) range[from--] := A_Index return range }
#2
-
Posted 10 September 2011 - 08:29 AM

No signature.
@tuncay, perhaps add a step?
#NoEnv SendMode Input SetWorkingDir %A_ScriptDir% s := "" For k, v in range(10, 0, -2) s .= k "=" v "`n" MsgBox % "range(10, 0, -2)`n" s s := "" ; same as above For k, v in range(10, 0, 2) s .= k "=" v "`n" MsgBox % "range(10, 0, 2)`n" s s := "" For k, v in range(3, 5) s .= k "=" v "`n" MsgBox % "range(3, 5)`n" s s := "" For k,v in range(0, 10, 2) s .= k "=" v "`n" MsgBox % "range(0, 10, 2)`n" s s := "" For k,v in range(4) s .= k "=" v "`n" MsgBox % "range(4)`n" s s := "" For k, v in range(-3, 6) s .= k "=" v "`n" MsgBox % "range(-3, 6)`n" s s := "" For k, v in range(3, -6, 2) s .= k "=" v "`n" MsgBox % "range(3, -6, 2)`n" s ExitApp Esc::ExitApp range(from, to="", step=1) { if (to="") { to := from from := 1 } Step:=Abs(Step) range := {} if (from < to) While, (from <= to) { range[A_Index] := from from += step } else While, (from >= to) { range[A_Index] := from from -= step } return range }
#3
-
Posted 10 September 2011 - 09:02 AM

Good idea hugov. Here same without Abs() (instead -step is enough) and direct access to object example. Also updated to be able to get a string list, instead of an object:
#NoEnv SendMode Input SetWorkingDir %A_ScriptDir% 3to5 := range(3, 5) MsgBox % 3to5[2] MsgBox % range(3, 5, 1, "`n") from := -9 to := 10 MsgBox % range(from, to)[19] MsgBox % range(from, to, 1, ",") s := "" For k,v in range(10) s .= v . "`n" MsgBox % s s := "" For k,v in range(-3, 2) s .= v . "`n" MsgBox % s s := "" For k,v in range(2, 5, -2) s .= v . "`n" MsgBox % s s := "" For k,v in range(5, -2, 2) s .= v . "`n" MsgBox % s range(from, to="", step=1, delim="") { if (to = "") to := from, from := 1 if (step < 0) step := -step if (delim != "") { range := "" if (from > to) While (from >= to) range .= from . delim, from -= step else While (from <= to) range .= from . delim, from += step StringTrimRight, range, range, % StrLen(delim) } else { range := {} if (from > to) While (from >= to) range[A_Index] := from, from -= step else While (from <= to) range[A_Index] := from, from += step } return range }
#4
-
Posted 10 September 2011 - 10:24 AM

No signature.
Sweet - I'd replace
StringTrimRight, range, range, % StrLen(delim)with
Range:=RTrim(Range, delim)and post the func in the Scripts sections if I were you
#5
-
Posted 10 September 2011 - 10:36 AM

I am working on it. I add documentation and make some test cases to be sure it works correct.and post the func in the Scripts sections if I were you
Why RTrim()? I remove the number of characters from the list, which may vary depending on the size of delim. In fact, I just remove last delimiter, which is added from the Loop.
#6
-
Posted 10 September 2011 - 10:42 AM

No signature.
I understand why, but RTRim is one less function to call as it skips the StrLen() and RTrim only removes the characters from the delimter, try it withWhy RTrim()?
MsgBox % range(3, 5, 1, "-DELIMITER-")But is doesn't matter that much, StringTrimRight just looks old in this modern looking code I think
perhaps
SubStr(range,1, (StrLen(Delim)*-1))looks more modern ;-)
(StringTrimRight might be removed/replaced from ahk v2 if I recall correctly so that might be one reason although not a very compelling one)
#7
-
Posted 10 September 2011 - 10:50 AM

On-topic: I don't see any particular need for another loop command.
Off-topic: RTrim("Unlimited-delimiter-", "-delimiter-") removes the trailing -, d, e, l, etc. and returns "Un". I doubt that's what you want. Also, StringTrimRight has already been removed from v2.
Off-topic: RTrim("Unlimited-delimiter-", "-delimiter-") removes the trailing -, d, e, l, etc. and returns "Un". I doubt that's what you want. Also, StringTrimRight has already been removed from v2.
#8
-
Posted 10 September 2011 - 12:09 PM

a few billion years B.C... Two water living creatures meet at the coast. Says one "If we had legs, we could go to land". Says the other "I don´t see any particular need for legs". At this day the evolution of snails and worms began.On-topic: I don't see any particular need for another loop command.
#9
-
Posted 11 September 2011 - 12:35 AM

All questions & answers are related to AHK 1.1.19.03 x64 Unicode
To this day, snails and worms don't have legs. Obviously they were right; they didn't need legs. :roll:
The survival of the human race does not depend on this feature. We'll get along just fine with the tried and true Loop command.
The survival of the human race does not depend on this feature. We'll get along just fine with the tried and true Loop command.
#10
-
Posted 11 September 2011 - 01:05 AM

Getting back on topic...
There is no need to add another loop command or use objects. A simple function seems to do the trick:
There is no need to add another loop command or use objects. A simple function seems to do the trick:
While InRange( index, 0, 10, 2 ) { ToolTip % index sleep 500 } Return InRange( ByRef index, from, to, step = 1 ) { ; Error checking n := from + to + step ErrorLevel := 1 If n is not number Return False If ( A_Index = 0 ) Return False ErrorLevel := 0 If ( step = 0 ) Step := 1 index := step * (A_Index - 1) + from if ( step < 0 ? index < to : index > to ) Return False Else Return True }
#11
-
Posted 11 September 2011 - 01:14 AM

Which needs to be posted at the bottom of any task-solution or Ask for Help reply, negating its usefulness to the point where nobody will ever use it :roll:
#12
-
Posted 11 September 2011 - 01:22 AM

Which post were you responding to?Which needs to be posted at the bottom of any task-solution or Ask for Help reply, negating its usefulness to the point where nobody will ever use it :roll:
#13
-
Posted 11 September 2011 - 01:44 AM

Yours
#14
-
Posted 11 September 2011 - 01:45 AM

@nimda Are you claiming that my solution doesn't work or are you claiming that every problem has to be solved by adding a new command to the language?
The solution posted works for integer and floating point numbers. It also allows for positive or negative steps. I don't see the problem.
The solution posted works for integer and floating point numbers. It also allows for positive or negative steps. I don't see the problem.
#15
-
Posted 11 September 2011 - 02:07 AM
