/*
ForEach.prg
In addition clasical FOR..NEXT loop, Harbour offers another FOR loop :
FOR EACH..NEXT.
Simplest syntax of this loop is :
FOR EACH <xValue> IN <xList>
...
NEXT
For arrays, this structure is equivalent to :
FOR <nIndex> := 1 TO LEN( <aArray> )
<xValue> := <aArray>[ nIndex ]
...
NEXT
Relations and rules for <xValue> and <xList> in FOR EACH loop :
If <xList> is ... <xValue> is ...
----------------- ----------------
<array> an element of <array>
<string> a single character in the <string>
<hash> <xValue> of <xKey> => <xValue> pair in the <hash>
Strings can be processed by indexing like arrays.
For string iteration, lib is xHB, so you need add
xHB lib calling in the your compile command:
hbmk2 -lxHB ForEach
and add your source prg file :
#include "xhb.ch"
*/
#include "xhb.ch"
PROCEDURE Main()
CLS
aFruits := { "appricot", "cherry", "melon", "pear", "grapes", "mulberry" }
c1Fruit := '' // Variable for iteration value must be exist
// before FOR ... statement
?
? "Traversing an array :"
?
FOR EACH c1Fruit IN aFruits
?? c1Fruit, ''
NEXT
/* Note that this loop is equivalent to :
?
FOR n1Fruit := 1 TO LEN( aFruits )
c1Fruit := aFruits[ n1Fruit ]
?? c1Fruit, ''
NEXT */
/* For a list in reverse order with classical FOR
?
FOR n1Fruit := LEN( aFruits ) TO 1 STEP -1
c1Fruit := aFruits[ n1Fruit ]
?? c1Fruit, ''
NEXT */
/* ... and with FOR EACH*/
?
? "Traversing an array in revers order :"
?
FOR EACH c1Fruit IN aFruits DESCEND
?? c1Fruit, ''
NEXT
/* Sometime we needs something like this :
?
FOR n1Fruit := 1 TO LEN( aFruits )
c1Fruit := aFruits[ n1Fruit ]
?? STR( n1Fruit, 2 ), ":", c1Fruit + ';'
NEXT */
/* FOR EACH loop allow us using some 'internal' functions;
but a 'special' way : */
?
? "Traversing an array with indexs :"
?
FOR EACH c1Fruit IN aFruits
?? STR( c1Fruit:__ENUMINDEX(), 2 ), ":", c1Fruit + ';'
NEXT
cString := "This is a string"
/* ... and a string example :
?
? "Iterating a string by FOR .. NEXT :"
?
FOR nIndex := 1 TO LEN( cString )
?? cString[ nIndex ]
NEXT */
c1Char := ''
?
? "Iterating a string :"
?
FOR EACH c1Char IN cString
?? c1Char
NEXT
?
? "Iterating a string in reverse order :"
?
FOR EACH c1Char IN cString DESCEND
?? c1Char
NEXT
?
? "Nested loop example :"
aArray := { "This is", "an array" }
c1String := ''
FOR EACH c1String IN aArray
? "----- Outer Loop -----"
? c1String:__ENUMINDEX(), c1String
? "----- Inner Loop -----"
FOR EACH c1Char IN c1String
? c1Char:__ENUMINDEX(), c1Char
NEXT
NEXT
?
? "Traversing a Hash : "
? "EnumKey EnumValue EnumBase[ EnumKey ]"
? "-------- ---------------- -------------------"
hSoftWare := { => }
HB_HKeepOrder( hSoftWare, .T. )
hSoftWare['MinGW ' ] := 'C Compiler '
hSoftWare['Harbour' ] := 'Clipper Compiler'
hSoftWare['HMG ' ] := 'GUI Library '
hProgram := NIL // { => }
FOR EACH hProgram IN hSoftWare
? hProgram:__ENUMKEY(), "=>", hProgram:__ENUMVALUE(),;
hProgram:__ENUMBASE()[hProgram:__ENUMKEY()] // Alternate syntax
NEXT
?
? "Multiple base, multiple value : "
aArrayNr := { 1, 2, 3 }
aArrayEn := { "one", "two", "three" }
aArrayFr := { "un", "deux", "Trois" }
cNumNr := 0
cNumEn := ''
cNumFr := ''
FOR EACH cNumNr, cNumEn, cNumFr IN aArrayNr, aArrayEn, aArrayFr
? cNumNr, cNumEn, cNumFr
NEXT
@ MAXROW(), 0
WAIT "EOF ForEach.prg"
RETURN // ForEach.Prg.Main()

Like this:
Like Loading...
Related
You are welcome 🙂
Wrong: Clip has a “FOR var IN …” and Harbour has a “FOR EACH var IN”.
Correct: Clip has a “FOR var IN …” and Harbour has “FOR var IN …” A.N.D. “FOR EACH var IN”. !
May be considered equivalent in function and not equivalent by syntax.
May be FOR EACH more speedy than other, but need test.
Happy Harbour’ing
Hi! I was wondering about the different FOR loops available in CLIP and Harbour.
Clip has a “FOR var IN …” and Harbour has a “FOR EACH var IN”.
Do you know if they are equivalent?
They seem to do the same thing, but I am not sure yet and couldn’t find anyone talking about it.
Pingback: Harbour Statements | Viva Clipper !