Loop structures: Difference between revisions

From Rosetta Code
Content added Content deleted
(β†’β€Žfor: added counting loop.)
Line 116: Line 116:
int i;
int i;
for {i=0; i<10; ++i) {
for (i=0; i<10; ++i) {
// The code here will be performed 10 times.
// The code here will be performed 10 times.
// The first part in the for-statement (i=0) is the initialization,
// The first part in the for-statement (i=0) is the initialization,

Revision as of 21:25, 16 October 2007

Task
Loop structures
You are encouraged to solve this task according to the task description, using any language you may know.
Control Structures

These are examples of control structures. You may also be interested in:


In this task, we document loop structures offered by different languages.

Ada

Simple Loop

The simple loop in Ada produces an infinite loop.

loop
   -- do something
end loop;

Any loop can be terminated by the exit reserved word.

loop
   -- do something
   if some-condition then
      exit;
   end if;
   -- do somthing else
end loop;

The short-hand notation for expressing the exit condition is:

loop
   -- do something
   exit when some-conditon;
   -- do something else
end loop;

While loop

while some-condition loop
   -- do something
end loop;

For loop

The for loop in Ada iterates over a specified range of discrete values. Ranges are an important concept in Ada. Ranges are always expressed in the form of lowest..highest. The loop control variable always takes on the type of the specified range. The loop control variable is read-only within the loop, and has a scope only within the loop.

Iteration over a literal range:

for I in 1..10 loop
   Put(I);
end loop;

You can also employ a range defined earlier in your code.

subtype Month_Number is Integer range 1..12;

for I in Month_Number loop
   Put(I);
end loop;

Ranges are also defined for the indices for arrays. Ada array indices can begin at any value, not just 0 or 1.

type Balanced_Index is range -10..10;
type My_Array_Type is array(Balanced_Index) of Integer;
My_Array : My_Array_Type;

for I in My_Array'Range loop
   Put(My_Array(I));
end loop;

AppleScript

repeat-until

set i to 5
repeat until i is less than 0
       set i to i - 1
end repeat
repeat
       --endless loop
end repeat

repeat-with

       repeat with i from 1 to 20
               --do something
       end repeat
       set array to {1,2,3,4,5}
       repeat with i in array
               display dialog i
       end repeat

Befunge

Befunge does not have specific loop statements, but any type of loop construct can be created using the branch (_|) skip (#) and direction (<>v^) commands. For example, the following is one possible structure for a while loop:

enter > test v
      ^ body _ exit

This program is like a for-loop in other languages, printing the digits from nine down to zero.

9>:.:#v_@
 ^ -1 <

C

while

Compiler: GCC 4.1.2

int main (int argc, char ** argv) {
  int condition = 1;

  while ( condition ) {
    // Do something
    // Don't forget to change the value of condition.
    // If it remains nonzero, we'll have an infinite loop.
  }
}

do-while

int main (int argc, char ** argv) {
  int condition = ...;
 
  do {
    // Do something
    // The difference with the first loop is that the
    // code in the loop will be executed at least once,
    // even if the condition is 0 at the beginning,
    // because it is only checked at the end.
    // Don't forget to change the value of condition.
    // If it remains nonzero, we'll have an infinite loop.
  } while ( condition );
}

for

int main (int argc, char ** argv) {
  int i;
 
  for (i=0; i<10; ++i) {
    // The code here will be performed 10 times.
    // The first part in the for-statement (i=0) is the initialization,
    // and is executed once before the loop begins.
    // The second part is the end condition (i<10), which is checked
    // every time the loop is started, also the first time;
    // the loop ends if it is false.
    // The third part (++i) is performed every time the code in the loop
    // is at the end, just before the end condition is checked.
  }
}

while with continue

The continue statement allows you to continue execution at the beginning of the loop, skipping the rest of the loop. In C you can only do this with the most inner loop. You can also do this with do-while and for.

int main (int argc, char ** argv) {
  int condition = 1;

  while ( condition ) {
    // Do something

    if (other condition)
      continue; // Continue at the beginning of the loop

    // Do something else
    // This part is not executed if other condition was true
  }
}

while with break

The break statement allows you to stop a loop. In C you can only break from most inner loop. You can also do this with do-while and for.

int main (int argc, char ** argv) {
  int condition = 1;

  while ( condition ) {
    // Do something

    if (other condition)
      break; // Continue after the the loop

    // Do something else
    // This part is not executed if other condition was true
  }
}

C++

Run-Time Control Structures

See C

Delphi

See Pascal

Forth

DO-LOOP

( limit start ) DO ( iterated statements ) LOOP
( limit start ) DO ( iterated statements ) ( increment ) +LOOP
LEAVE \ exits a DO loop
UNLOOP EXIT \ cleans up loop counters from return stack before returning from the current word

example: Two standard iterations

10 0 DO I . LOOP      \ Prints the numbers from 0 to 9
10 0 DO I . 2 +LOOP   \ Prints the even numbers from 0 to 8

BEGIN-UNTIL

BEGIN ( iterated statements ) ( conditional ) UNTIL

example: Counts down from a given number to zero

: COUNTDOWN ( n -- )  BEGIN  DUP CR .  1- DUP 0< UNTIL  DROP ;

BEGIN-AGAIN

BEGIN ( iterated statements ) AGAIN

example: echo user's input

: FOREVER ( -- )   BEGIN  KEY EMIT  AGAIN ;

BEGIN-WHILE-REPEAT

BEGIN  ( conditional ) WHILE  ( iterated statements )  REPEAT

example: counts down from a given number to one

: COUNTDOWN ( n -- )  BEGIN  DUP WHILE  CR DUP . 1-  REPEAT  DROP ;

Additional WHILE clauses may be added to a loop, but each extra WHILE requires a matching THEN after the REPEAT.

Mixed Structures

Because Forth's compiler is laid bare to the programmer, it is quite easy to both define your own looping structures or combine existing structures in interesting ways. The rules for such combining are somewhat involved, though discussions can be found in the gforth user's manual, among other places. These more complex looping constructs can make up for Forth's lack of a "break" word, and can allow expressing complex loops without resorting to boolean variables.

A good example of a useful combination is this complex loop:

BEGIN
  ( condition 1 )
WHILE
  ( condition 2 )
UNTIL
  ( condition 2 succeeded )
ELSE
  ( condition 1 failed )
THEN

An example of using this idiom in practice might be this pseudo-Forth

BEGIN
  read-next-record
WHILE
  found-record
UNTIL
  process-record
ELSE
  error" Ran out of records looking for the right one!"
THEN

Groovy

While Loops

while (true) {
  println 'groovy'
}

For Loops


 // iterate over a range
 x = 0
 for (i in 1..3) { x += i }
 assert x == 6

 // iterate over a list
 x = 0
 for (i in [1, 2, 3]) { x += i }
 assert x == 6

 // iterate over an array
 x = 0
 for (i in (1..3).toArray()) { x += i }
 assert x == 6

 // iterate over a map's key/value pairs
 x = 0
 for (i in map) { x += i.value }
 assert x = 6

 // iterate over a map's values
 x = 0
 for (i in map.values()) { x += i }
 assert x == 6

 // iterate over the characters in a string
 text = 'abc'
 list = []
 for (c in text) { list.add(c) }
 assert list == ['a', 'b', 'c']

Each

 def stringList = [ "java", "perl", "python", "ruby" ];

 def stringMap = [ "Su" : "Sunday", "Mo" : "Monday", "Tu" : "Tuesday",
                  "We" : "Wednesday", "Th" : "Thursday", "Fr" : "Friday",
                  "Sa" : "Saturday" ];

 stringList.each() { print " ${it}" }; println "";
 // java perl python ruby

 stringMap.each() { key, value -> println "${key} == ${value}" };
 // Su == Sunday
 // We == Wednesday
 // Mo == Monday
 // Sa == Saturday
 // Th == Thursday
 // Tu == Tuesday
 // Fr == Friday  

 stringList.eachWithIndex() { obj, i -> println " ${i}: ${obj}" };
 // 0: java
 // 1: perl
 // 2: python
 // 3: ruby

 stringMap.eachWithIndex() { obj, i -> println " ${i}: ${obj}" };
 // 0: Su=Sunday
 // 1: We=Wednesday
 // 2: Mo=Monday
 // 3: Sa=Saturday
 // 4: Th=Thursday
 // 5: Tu=Tuesday
 // 6: Fr=Friday

IDL

It should be noted that IDL programmers tend to avoid loops -- most of the time loops are used to access the elements of arrays or vectors, and since IDL is an array language the same purpose can almost always be served in a faster, more elegant and more readable way though any of the array operations.

for

 for i=0,50,2 do print,i

prints out every second number starting at 0 stopping at 50. Wherever a single command can go in IDL, there can always go a begin...end pair with arbitrary amount of code in between. Thus the above can also read

 for variable = start, stop [,increment] do begin
   ;some code here
   ;some more code
 endfor

It is allowed but not required to use the appropriate "type of end" - i.e. it would be allowed to just say "end" instead of "endfor". However "endfor" (and "endwhile", "endif" etc) will throw an error if the wrong one is encountered at compile time and thus it is recommended to always use the more descriptive form since it makes debugging a lot easier.

while

 while condition do command

Same extensions as above:

 while running do begin
   ; various snippets of code that might change the variable 
   ; "running" from something true to something false
 end[while]

repeat

 repeat command until condition

etc

goto

'Goto' exists and can in principle be forced to make a loop:

 label: 
   ;some code
 [if condition then $]
 goto label

break

The break statement will immediately terminate the current innermost for, while, repeat, if, case or switch without having to resort to a goto.

Java

while

   while(true)
   {
       foo();
   }

do-while

   do
   {
       foo();
   }
   while (true)

for

   for(int i = 0; i < 5; i++)
   {
       foo();
   }

foreach

Platform: J2SE 1.5.0

 Object[] objects;
 // ...
 for (Object current : objects[]) {
   // ...
 }
 int[] numbers;
 // ...
 for (int i : numbers) {
   // ...
 }

JavaScript

while

   while(true) {
       foo();
   }

do while

   do {
       foo();
   } while(test);

for

   for(var i = 0; i < 5; i++) {
       foo();
   }

for in

//iterate through property names of an object

var obj = {prop1:"a", prop2:"b", prop3:"c"};
for (var key in obj)
  alert( key + ' is set to ' + obj[key] );

for each in

//iterate through property values of an object

var obj = {prop1:"a", prop2:"b", prop3:"c"};
for each(var element in obj)
  alert( element );

newLISP

dotimes

Interpreter: newLISP v.9.0

(dotimes (x 10) (println (+ x 1)))

do-until

Interpreter: newLISP v.9.0

(set 'x 1)
(do-until (= x 10) (inc 'x) (println x))

do-while

Interpreter: newLISP v.9.0

(set 'x 1)
(do-while (< x 10) (inc 'x) (println x))

for

Interpreter: newLISP v.9.0

(for (x 1 10) (println x))

Object Pascal

See Pascal

Objective-C

See C

Pascal

while

Compiler: Turbo Pascal 7.0

 WHILE condition1 DO
   BEGIN
     procedure1;
     procedure2;
   END;

repeat-until

Compiler: Turbo Pascal 7.0

 REPEAT
   procedure1;
   procedure2;
 UNTIL condition1;

for

Compiler: Turbo Pascal 7.0

 FOR counter := 1 TO 10 DO
   BEGIN
     procedure1;
     procedure2;
   END;

Compiler: Delphi 1.x and above

 Var
  Counter : char ;
 FOR counter := 'A' TO 'Z' DO
   BEGIN
     procedure1;
     procedure2;
   END;

Perl

while

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my $condition1 = 0;

while ( $condition1 ) {
 # Do something.
 # Remember to change the value of condition1 at some point.
}

do-while

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my $condition1 = 0;

do {
 # Do something.
 # Remember to change the value of condition1 at some point.
} while ( $condition1 );

until

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my $condition1 = 1;

until ( $condition1 ) {
 # Do something.
 # Remember to change the value of condition1 at some point.
}


do-until

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my $condition1 = 1;

do {
 # Do something.
 # Remember to change the value of condition1 at some point.
} until ( $condition1 );

for

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my $limit = 5;

for ( my $iterator = 0; $iterator < $limit; $iterator++ ) {
  # Do something
}

# for-variant, implicit iteration
for (0..$limit) {
  # Do something
}

do_something() for 0..$limit;

foreach

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my @numbers = (1, 2, 3);
my %names = (first => "George", last => "Jetson");

foreach my $number (@numbers) {
  # Do something with $number
}

foreach my $key (keys %names) {
  # Do something with $key (values are accessible as %names{$key} )
}

map

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my @numbers = (1, 2, 3);
my @target;

@target = map {
  # Do something with $_
} @numbers;

@target = map($_ + 1, @numbers);

sub a_sub {
  # Do something with $_
}

@target = map a_sub @numbers;

grep

Interpreter: Perl 5.8.8

#!/usr/bin/perl -w

use strict;

my @people = qw/Bobbie Charlie Susan/;
my @target;

@target = grep {
  # Discriminate based on $_
} @people;

# Feed grep into map, this picks out elements 1, 3, 5, etc.
@target = map($people[$_], grep($_ & 1, 0..$#people));

# Pick out the diminutive names
@target = grep(/ie$/, @people);

sub a_sub {
  # Do something with $_, and return a true or false value
}

@target = grep a_sub @people;

PHP

while

while(ok()) {
    foo();
    bar();
    baz();
}

do-while

$i = 0;
do {
    echo $i;
} while ($i > 0);

for

for($i = 0; $i < 10; ++$i) {
    echo $i;
}

foreach

foreach(range(0, 9) as $i) {
    echo $i;
}

foreach is only used for arrays, which is not obvious from the above example

foreach($array as $key => $value) {
    echo $key.' is '.$value;
}

Pop11

while

Pop11 offers multiple looping constructs. Basic one is while loop:

 5 -> n;
 while n > 0 do 
     printf(n, '%p\n');
     n - 1 -> n;
 endwhile;

until

Variant of while is until loop:

until condition do /* Action */ enduntil;

is equivalent to:

while mot(condition) do /* Action */ endwhile;

for

One can process all elements of a list:

 for x in [a b c] do x => endfor;

It is possible to simultaneously process multiple lists:

for x y in [a b c], [1 2 3] do [^x ^y] => endfor;

in first iteration sets x to "a" and y to 1, in the second x is "b" and y is 2, in the third (last) iteration x is "c" and y is 3. The iteration ends when the shortest list is exhausted.

Somtimes one wants to process tails of the list, to do this use on keyword instead of in keyword:

for x on [a b c] do x => endfor;

in first iteration sets x to [a b c], in the second to [b c], etc...

There is also "counting" version of for loop:

for x from 2 by 2 to 7 do x => endfor;

goes trough 2, 4 and 6. Ommited by frase means by 1.

There is alse a C-like for loop:

for action1 step  action2 till condition do /* Actions */ endfor;

is equivalent to

action1
while not(condition) do
   /* Actions */
   action2
endwhile;

There are more specialized kinds of loops, but we skip them here.

quitloop quitif quitunless

Inside loops one can use control transfers to prematuraly exit the loop or end current iteration and start the next one:

while true do n - 1 -> n; quitif(n=0); endwhile;

quits loop when n=0. quitloop unconditionally quits loop, quitunless(x) is equivalent to quitif(not(x)).

nextloop nextif nextunless

Similarely to quitloop nextloop unconditionally ends current iteration and starts the new one, nextif(x) ends current iteration when x is true, nextunless(x) is equivalent to nextif(not(x)). The loop control transfers can be also used inside for (and until) loops.

Finally, it is frequently possible to avoid explicit iteration using higher order map functions (like appdata and mapdata).

PostScript

The "for" operator expects three numbers and a procedure on the stack. It will consume all four arguments then it will push the first number on the stack, execute the procedure, increase the first number by the second number, push it on the stack, execute the procedure etc until the third number is reached. For example

10 12 200 
  {dup moveto 100 0 lineto} 
  for 
stroke

will add lines to the currentpath that start at coordinates {10,10}; {22,22}; {34,34} ... and all end at {100,0}. The "stroke" operator then renders these lines on the current output device (usually a screen or a piece of paper).

Python

for

Typically for is used to iterate over items in an iteratable:

for x in ["foo", "bar", "baz"]:
    print x

It is also used to create indexes:

for i in xrange(10):
    print numbers[i]

Optional else is executed unless break was called during iteration:

for i in numbers:
    if item < 0:
        break
else:
    print 'all numbers are positive'

list comprehension

Typically used when you want to create a list and there is little logic involved. Faster then for loop:

positives = [n for n in numbers if n > 0]

while

Typical use:

while 1:
    # Do stuff...
    if condition:
        break

You can add else, which is executed only if the tested expression is false. Typically not used.

while running:
    # Do stuff...
    if condition:
        running = 0
else:
   print 'stopped'

Ruby

while

while true do
  foo
end

for

for i in 0..4 do
  foo
end

each

['foo', 'bar', 'baz'].each do |x|
  puts x
end

collect

array = ['foo', 'bar', 'baz'].collect do |x|
  foo x
end

map

array = ['foo', 'bar', 'baz'].map {|x| foo x }

inject

string = ['foo', 'bar', 'baz'].inject("") do |s,x|
  s << x
end
sum = ['foo', 'bar', 'baz'].inject(0) do |s,x|
  s + x.size
end
product = ['foo', 'bar', 'baz'].inject(1) do |p,x|
  p * x.size
end
boolean = ['foo', 'bar', 'baz'].inject(true) do |b,x|
  b &&= x != 'bar'
end

Seed7

In Seed7 new statements can be declared easily. This feature is not explained here. Here are examples of the predefined loops:

while

while TRUE do
  foo;
end while;

repeat

repeat
  foo;
until FALSE;

for

for i range 0 to 4 do
  foo;
end for;
for i range 4 downto 0 do
  foo;
end for;
for stri range []("foo", "bar", "baz") do
  writeln(stri);
end for;

Smalltalk

timesRepeat

 10 timesRepeat: [ expression ].

iterating over a collection

 ( collection ) do: [ expression ].
 ( collection ) collect: [:element | element sendMessageToElement].
 #(1 2 3 4) inject: 5 into: [:sum :number | sum + number]

whileTrue/whileFalse

 x := 0.
 [ x < 100 ]
      whileTrue: [ x := x + 10.].
 [ x = 0 ]
      whileFalse: [ x := x - 20.].

simple looping

 1 to: 5 do: [:number | Transcript show: 'Here is a number: ' number printString ; cr]
 (-50 to: 50 by: 4) do: [:number | Transcript show: number ; cr]

Tcl

foreach

foreach i {foo bar baz} {
    puts "$i"
}

Note that foreach also accepts multiple variables:

foreach {x y} {1 2 3 4} {
    puts "$x,$y"
}

And also multiple lists:

foreach i {1 2 3} j {a b c} {
    puts "$i,$j"
}

Or any combination of variables/list:

foreach i {1 2 3} {x y} {a b c d e f} {
    puts "$i,$x,$y"
}

for

 for {set i 0} {$i < 10} {incr i} {
     puts $i
 }

It bears noting that the three parts of the for loop do not have to consist of "initialize variable", "test value of variable" and "increment variable". This is a common way to think of it as it resembles the "for" loop in other languages, but many other things make sense. For example this for-loop will read a file line-by-line:

 set line ""
 for { set io [open test.txt r] } { ![eof $io] } { gets $io line } {
   if { $line != "" } { ...do something here... }
 }

(This is a somewhat awkward example; just to show what is possible)

while

 set i 0
 while {$i < 10} {
     puts [incr i]
 }

Toka

countedLoop

Counts up or down until the boundaries are met.

10 0 [ i . ] countedLoop
0 10 [ i . ] countedLoop

whileTrue

Repeatedly executes a quote until the quote returns true.

100 [ dup . 1 - dup 0 <> ] whileTrue

whileFalse

Repeatedly executes a quote until the quote returns true.

0 [ dup . 1 + dup 101 = ] whileFalse

UNIX Shell

for

Interpreter:' Bourne Again SHell

A simple loop that counts from 1 to 10.

#!/bin/bash
for ((x = 1; $x <= 10; x = $x + 1 ))
do
 echo $x
done

for...in

Interpreter: Bourne Again SHell

A loop that iterates through all of the (whitespace-delimited) members of ARRAY.

#!/bin/bash
ARRAY="VALUE1 VALUE2 VALUE3 VALUE4 VALUE5"

for ELEMENT in $ARRAY
do
 echo $ELEMENT # Print $ELEMENT
done

while

Interpreter: bourne SHell

#!/bin/sh
x=1
while [ $x -lt 101 ]
do
  echo $x
  x=`expr "$x" + 1`
done


Interpreter: Bourne Again SHell

 #!/bin/bash
 while true
 do
   ...
 done