FOR EACH..NEXT loop

/*
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()

ForEach

3 responses to “FOR EACH..NEXT loop

  1. 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

  2. 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.

  3. Pingback: Harbour Statements | Viva Clipper !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.