Huju: Slice Array

Hi,

ich möchte ein Element aus einem Array löschen, wenn eine gewisse Bedingung zutrifft.

Hier mal wie ich das realisiert habe.

  
my @browser = ("NS", "IE", "IE", "Opera","Safari");  
my $i=0;  
foreach (@browser)  
{  
        print "A $_ \n";  
        if ($_ eq "IE") {splice(@browser, $i, 1);} $i++;  
}  
foreach (@browser)  
{ print "N $_ \n";}  
  

Ausgabe:

A NS  
A IE  
A Opera  
A Safari  
N NS  
N IE  
N Opera  
N Safari  

Wie man sieht, klappt das rauslöschen mit slice, aber das nächste Element in der foreach-Schleife wird dann "ignoriert". Jemand ne Idee, wie man das richtig macht?

  1. Wie man sieht, klappt das rauslöschen mit slice, aber das nächste Element in der foreach-Schleife wird dann "ignoriert". Jemand ne Idee, wie man das richtig macht?

    Ich hab zwar keine Ahnung von Perl, aber ich vermute dass du du beim entfernen mit slice den mummerischen Zeiger der foreach-Schleife nicht beeinflusst, das Array aber neu nummeriert wird. dh. der Zeiger stimmt dann nicht mehr, weil er auf ein Element weiter zeigt - du musst den Zeiger dann also eins zurückverschieben.

  2. ich möchte ein Element aus einem Array löschen, wenn eine gewisse Bedingung zutrifft.

    Du willst aber nicht nur doppelte Elemente entfernen? Das wäre nämlich eine FAQ

    Struppi.

    1. ich möchte ein Element aus einem Array löschen, wenn eine gewisse Bedingung zutrifft.

      Du willst aber nicht nur doppelte Elemente entfernen? Das wäre nämlich eine FAQ

      Nein, das war nur ein Beispiel.

      1. Nein, das war nur ein Beispiel.

        OK, dann suchst du grep:

        @browser = grep $_ ne 'IE', @browser;

        Struppi.

        1. Nein, das war nur ein Beispiel.

          OK, dann suchst du grep:

          @browser = grep $_ ne 'IE', @browser;

          Ich komm glaub um eine Schleife nicht drum rum,
          da meine Abfrage nicht ganz so simple wie das Beispiel ...

          my $ping = Net::Ping->new("icmp");  
          foreach my $switch (@SWITCHES)  
          {  
            if (!$ping->ping($switch,3))  
            {  
              print "Switch $switch not reachable.\n";  
              # >>> Hier möchte ich nun $switch aus dem array @SWITCHES entfernen  
            }  
          }
          
          1. Nein, das war nur ein Beispiel.

            OK, dann suchst du grep:

            @browser = grep $_ ne 'IE', @browser;

            Ich komm glaub um eine Schleife nicht drum rum,

            Das glaube ich nicht.

            da meine Abfrage nicht ganz so simple wie das Beispiel ...

            Das spielt keine Rolle, du kannst auch einen Block als Ausdruck verwenden.

            my $ping = Net::Ping->new("icmp");

            foreach my $switch (@SWITCHES)
            {
              if (!$ping->ping($switch,3))
              {
                print "Switch $switch not reachable.\n";
                # >>> Hier möchte ich nun $switch aus dem array @SWITCHES entfernen
              }
            }

              
            Warum machst du es nicht umgekehrt? Alle erfolgreichen Abfragen, in ein neues Array eintragen. Da diese vorgehensweise nicht geht, wie andreas schon erläutert hat.  
              
            Struppi.
            
  3. Hi,

    foreach (@browser)
    {
            if ($_ eq "IE") {splice(@browser, $i, 1);} $i++;

    Kids, don't do that at home ...

    Zitat aus <http://perldoc.perl.org/perlsyn.html#Foreach-Loops@Perldoc zu foreach>

    If any part of LIST is an array, foreach  will get very confused if you add or remove elements within the loop body, for example with splice. So don't do that.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
    1. Hi,

      foreach (@browser)
      {
              if ($_ eq "IE") {splice(@browser, $i, 1);} $i++;

      Kids, don't do that at home ...

      Zitat aus <http://perldoc.perl.org/perlsyn.html#Foreach-Loops@Perldoc zu foreach>

      If any part of LIST is an array, foreach  will get very confused if you add or remove elements within the loop body, for example with splice. So don't do that.

      Okay, was ist also die Alternative?
      Temporäres array mit push füllen und nach der Schleife dem orginalen zuweisen?