opi: Unterschied zwischen for und foreach

Hallo zusammen,

kann mir jemand den genauen Unterschied zwischen einer for- und einer
foreach-Schleife erklären?

Bisher bin ich immer davon ausgegangen, dass eine for-Schleife nur
dazu genutzt wird, um einen Zähler in der Bedingung zu nutzen und
eine foreach-Schleife, um Elemente eines Arrays zu modifizieren.

"Eine Modifikation der Schleifenvariable führt also zu einer
Modifikation des ursprünglichen Arrays."

Ich bin immer davon ausgegangen, das beide Schleifen etwas können,
was die Andere nicht kann - also bezüglich Zähler und Modifikation.
Nun komme ich ein wenig durcheinander. Ich möchte das gerne mal mit
einem Beispiel zeigen:

  
my @array;  
  
push @array, "foo";  
push @array, "foo";  
push @array, "foo";  
  
# for modifiziert das Array  
  
s/foo/bar/ for @array;  
print "$_\n" for @array;  
  
# foreach hat einen Zähler  
  
foreach ( my $i = 0 ; $i <= 10 ; $i++ ) {  
   print "$i\n";  
}  

Ebenso habe ich mittlerweile sehr oft gesehen, dass für das Durch-
laufen von Hashes eine for- statt einer foreach-Schleife genutzt
wird. Gibt es hierfür einen besonderen Grund oder eine Faustregel,
wann ganz speziell welche Schleife genutzt werden sollte oder sogar
genutzt werden muss?

Oder ist die for-Schleife nur ein Trostpflaster für die
C-Programmierer? :-)

Bislang habe ich ganz strickt das Schema verfolgt:

for für Zählschleifen
foreach zum Durchlaufen von Arrays und Hashes

und nü weiß ich net mehr was richtiger ist ... *URGS* :-)

Greez,
opi

--
Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
  1. Hallo opi.

    Rein interessehalber:

    foreach ( my $i = 0 ; $i <= 10 ; $i++ ) {
       print "$i\n";
    }

      
    Von Perl habe ich so gut wie keine Ahnung, aber sieht eine foreach-Schleife dort so aus?  
      
    Für mich ist obiges eine for-Schleife.  
      
    Ich kenne foreach nur folgendermaßen:  
      
    ~~~php
    $foo = array('Foo', 'Bar', 'Baz');  
      
    foreach ($foo as $foochild) {  
      echo $foochild.'<br />';  
    }
    

    Einen schönen Dienstag noch.

    Gruß, Ashura

    1. Hallo Ashura,

      Rein interessehalber:

      Von Perl habe ich so gut wie keine Ahnung, aber sieht eine foreach-Schleife dort so aus?

      Da fragst du mich aber was. Bisher bin ich ja auch immer davon
      ausgegangen, dass foreach-Schleifen so "foreach(@ARRAY)" aussehen und
      for-Schleifen so "for(my $i=0;$i<10;$i++)" aussehen. Aber da beides
      funktioniert, wüßte ich nun gerne, warum es die beiden Schleifen
      gibt, wenn beide augenscheinlich exakt das gleiche können.

      Für mich ist obiges eine for-Schleife.

      Ich kenne foreach nur folgendermaßen:

      $foo = array('Foo', 'Bar', 'Baz');

      foreach ($foo as $foochild) {
        echo $foochild.'<br />';
      }

        
      Ich habe nicht die geringste Ahnung von php, sorry :-)  
        
      Greez,  
      opi
      
      -- 
      Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|  
      
      
    2. Rein interessehalber:

      foreach ( my $i = 0 ; $i <= 10 ; $i++ ) {
         print "$i\n";
      }

      
      >   
      > Von Perl habe ich so gut wie keine Ahnung, aber sieht eine foreach-Schleife dort so aus?  
        
      Naja, es ist ja schon geklärt for und foreach ist das Gleiche  
        
      
      > Ich kenne foreach nur folgendermaßen:  
      >   
      > ~~~php
      
      $foo = array('Foo', 'Bar', 'Baz');  
      
      >   
      > foreach ($foo as $foochild) {  
      >   echo $foochild.'<br />';  
      > }
      
      

      foreach in Perl ist lediglich dafür da, um solche Schleifen von den anderen zu unterscheiden. Daher wird es üblicherweise auch so genutzt:

      @foo = ('Foo', 'Bar', 'Baz');  
        
      foreach my $foochild (@foo) {  
         echo $foochild.'<br />';  
      }
      

      Struppi.

      1. 你好 Struppi,

        foreach in Perl ist lediglich dafür da, um solche Schleifen von den
        anderen zu unterscheiden. Daher wird es üblicherweise auch so genutzt:

        @foo = ('Foo', 'Bar', 'Baz');

        foreach my $foochild (@foo) {
           echo $foochild.'<br />';
        }

          
        Nunja, in dem Fall würde man eher join benutzen ;)  
          
        `print join "<br />",@foo;`{:.language-perl}  
          
        再见,  
         克里斯蒂安  
        
        -- 
        [Wundert euch nicht, …](http://ck.kennt-wayne.de/wundert-euch-nicht,...) | [Noch eine Block-Installation: SELFHTML Aktuell](http://ck.kennt-wayne.de/noch-eine-block-installation:-selfhtml-aktuell)  
        <g[oma]> peter lustig ist auf jeden fall besser als peter huth, obwohl der auch lustig ist.  
          
        <http://wwwtech.de/>  
        
        
        1. Nunja, in dem Fall würde man eher join benutzen ;)

          print join "<br />",@foo;

          Was sicher auch wieder ein paar Millisekundenbruchteile spart ;-)

          Struppi.

  2. Hallo Opi,

    kann mir jemand den genauen Unterschied zwischen einer for- und einer
    foreach-Schleife erklären?

    Laut dem Kamelbuch (Programmieren mit Perl, Larry Wall, Tom Christiansen & Randal Schwartz, O'Reilly-Verlag) erwartet die for-Schleife drei Ausdrücke innerhalb der Klammern der Schleife: Einen Ausdruck, der den Anfangszustand der Schleifenvariable bestimmt, eine Bedingung, die die Schleifenvariable prüft, und einen Ausdruck, der den Zustand der Schleifenvariable verändert. [...]

    foreach wird genutzt, um den gleichen Code für jedes Element einer bekannten Menge von Skalaren, etwa eines Arrays, auszuführen ...
    Bei jeder foreach-Anweisung wird der in Klammern stehende Ausdruck so evaluiert, dass er eine Liste erzeugt. Dann wird die Schleifenvariable nacheinander zu einem Synonym für jedes Element der Liste gemacht, und der Codeblock wird für jedes Element einmal ausgeführt...

    Eine Konstruktion, die Ihnen häufig begenen wird, ist die Schleife über die sortierten Schlüssel eines Hashes:

    foreach $key (sort keys %hash) {

    ...

    Jetzt etwas klarer? Dein seltsames foreach-Beispiel verstehe ich überhaupt nicht. Wer wird so etwas wollen? Das ist eine Vergewaltigung von foreach.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz,

      Laut dem Kamelbuch (Programmieren mit Perl, Larry Wall, Tom Christiansen & Randal Schwartz, O'Reilly-Verlag) erwartet die for-Schleife drei Ausdrücke innerhalb der Klammern der Schleife: Einen Ausdruck, der den Anfangszustand der Schleifenvariable bestimmt, eine Bedingung, die die Schleifenvariable prüft, und einen Ausdruck, der den Zustand der Schleifenvariable verändert. [...]

      ach ja? Dann schlag mal im Buch Seite 293 (2. Auflage) auf...

      "Zugriff und Ausgabe bei Hashes von Hashes"

      for $familiy ( sort keys %HoH ) {
         ...
      }

      for $family ( sort { keys %{$HoH{$a}} <=> keys %{$HoH{$b}} } keys %HoH ) {
         ...
      }

      Soviel zu "erwartet die for-Schleife drei Ausdrücke innerhalb der Klammern" :-))

      foreach wird genutzt, um den gleichen Code für jedes Element einer bekannten Menge von Skalaren, etwa eines Arrays, auszuführen ...
      Bei jeder foreach-Anweisung wird der in Klammern stehende Ausdruck so evaluiert, dass er eine Liste erzeugt. Dann wird die Schleifenvariable nacheinander zu einem Synonym für jedes Element der Liste gemacht, und der Codeblock wird für jedes Element einmal ausgeführt...

      genau dieses tolle Buch habe ich auch vor mir liegen und eine
      Antwort auf meine Frage gesucht zwischen Seite 32 und 36 gesucht. :-)

      Eine Konstruktion, die Ihnen häufig begenen wird, ist die Schleife über die sortierten Schlüssel eines Hashes:

      foreach $key (sort keys %hash) {

      ...

      Jetzt etwas klarer? Dein seltsames foreach-Beispiel verstehe ich überhaupt nicht. Wer wird so etwas wollen? Das ist eine Vergewaltigung von foreach.

      Das war ja auch nicht meine Frage.

      Greez,
      opi

      --
      Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
      1. Hallo Opi,

        die Perl-Dokumentation weiss es:

        foreach ist ein Synonym für for :-) Das sollte alle Deine Fragen klären. Und die nicht erwarteten Schreibweisen sollte man meiner Meinung nach nicht nutzen, da sie offensichtlich zu Unverständnis führen.

        Freundliche Grüße

        Vinzenz

        1. Hallo,

          Hallo Opi,

          die Perl-Dokumentation weiss es:

          foreach ist ein Synonym für for :-) Das sollte alle Deine Fragen klären.

          Ja, das klärt allerdings alle Fragen.

          Und die nicht erwarteten Schreibweisen sollte man meiner Meinung nach nicht nutzen, da sie offensichtlich zu Unverständnis führen.

          Du glaubst garnicht, welchen Schrecken ich bekommen habe, als mir
          der Gedanke in den Kopf kam, nun all meine Skripts entsprechend
          bestimmter mir unbekannter Regeln ändern zu müssen :-)

          Nun... es kann alles bleiben, wie es ist. Dankeschön.

          Greez,
          opi

          --
          Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|
    2. Hi,

      Laut dem Kamelbuch (Programmieren mit Perl, Larry Wall, Tom Christiansen & Randal Schwartz, O'Reilly-Verlag) erwartet die for-Schleife drei Ausdrücke innerhalb der Klammern der Schleife:

      for gibt es in mehreren Varianten in Perl.

      for (2 + 19, 3 * 23, 5 / 29, 7 - 31, 11 + 37, 13, 17)
      {
          print $_."\n";
      }

      ist z.B. auch eine korrekte for-Schleife - mit deutlich mehr als 3 Ausdrücken in der Klammer ;-)

      cu,
      Andreas

      --
      Warum nennt sich Andreas hier MudGuard?
      Schreinerei Waechter
      Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
      1. Hallo Andreas,

        for (2 + 19, 3 * 23, 5 / 29, 7 - 31, 11 + 37, 13, 17)

        somit eine Liste und nachdem ich inzwischen weiß, dass for und foreach Synonyme sind (ja, das war mir bis heute durchaus unbekannt),

        {
            print $_."\n";
        }

        ist z.B. auch eine korrekte for-Schleife - mit deutlich mehr als 3 Ausdrücken in der Klammer ;-)

        die mir dennoch mit foreach besser gefallen würde. In der Kürze liegt nicht immer die Würze :-)

        ist die Funktionsweise klar. Aber ich vermute, dass die Autoren des von mir zitierten Textes schon wussten, was sie schreiben ...

        Freundliche Grüße

        Vinzenz

      2. Tag MudGuard.

        for gibt es in mehreren Varianten in Perl.

        Ja, um genau zu sein in zwei: als Statement Modifier und als Compound Statement.

        ist z.B. auch eine korrekte for-Schleife - mit deutlich mehr als 3 Ausdrücken in der Klammer ;-)

        Nö, das ist keine for-Schleife im engeren Sinne :-)

        Siechfred

  3. Hallo,

    The foreach keyword is actually a synonym for the for keyword, so you can use foreach for readability or for for brevity.

    http://wiki.perl-community.de/bin/view/Perldoc/perlsyn

    gruss

    --
    no strict;
    no warnings;
    79.78 cups of Coffee (Brewed) + Me = Death
    Terrorific!