Slice Array
Huju
- perl
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?
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.
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.
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.
Nein, das war nur ein Beispiel.
OK, dann suchst du grep:
@browser = grep $_ ne 'IE', @browser;
Struppi.
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
}
}
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.
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
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?