Schrift
[thread]12659[/thread]

Bei "for" durch einen Array delete auf sich selbst anwenden



<< >> 6 Einträge, 1 Seite
Gast Gast
 2008-10-20 13:25
#115648 #115648
Hallo zusammen

Folgendes Beispiel:

Code: (dl )
1
2
3
4
5
6
7
my @array = (hans, susanne, peter);

for (@array) {
if (/susanne/) {
# element susanne rauslöschen
}
}


Wie mache ich sowas? Gibt es eine Spezialvariable, die auf das aktuelle Element zeigt so, dass ich dieses mittels delete löschen kann?

Grüsse
pq
 2008-10-20 13:42
#115649 #115649
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
Code (perl): (dl )
@array = grep { !m/susanne/ } @array;

ich könnte mir aber vorstellen, dass du statt einer regex einen vergleich willst. diese regex
würde auch alle elemente löschen, in denen irgendwo in der mitte 'susanne' vorkommt.

desweiteren ist
my @array = (hans, susanne, peter);
falsche syntax! um strings gehören anführungszeichen.
bitte immer Wiki:strict und warnings benutzen.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Ronnie
 2008-10-20 13:51
#115650 #115650
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Mann kann ein Array auch rückwärts durchlaufen und die entsprechenden Elemente mit splice entfernen, aber die Lösung von pq ist empfehlenswerter!
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
use Carp;

my @list    = qw{ Tim Bob Susanne Olli Nancy };
my $idx     = $#list;
$list[$idx] eq 'Susanne' and splice (@list, $idx, 1) while($idx-- > 0);

print Dumper \@list;

Geht auch mit einer for-Schleife! Ist wahrscheinlich leichter nachzuvollziehen:
Code (perl): (dl )
1
2
3
4
5
for my $i (reverse (0..$idx)) {
    if ($list[$i] eq 'Susanne') {
        splice (@list, $i, 1);
    }
}
pq
 2008-10-20 14:32
#115651 #115651
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
wenn insgesamt nur wenige elemente gelöscht werden bei einem grossen array, ist vermutlich
die splice-variante effizienter.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Linuxer
 2008-10-20 14:55
#115652 #115652
User since
2006-01-27
3875 Artikel
HausmeisterIn

user image
Verdammte Neugier:

Bei Verwendung eines Vergleichs ist die grep Suche etwas schneller.

quick'n'dirty benchmarked:

Code: (dl )
1
2
3
4
5
6
@list has 17576 elements!
Rate grep_re splice_re splice_eq grep_eq
grep_re 24.6/s -- -36% -46% -53%
splice_re 38.6/s 57% -- -16% -27%
splice_eq 45.9/s 87% 19% -- -13%
grep_eq 52.8/s 115% 37% 15% --


Used this dirt:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw( cmpthese );


my @list = ( ( 'AAA' .. 'ZZZ' ) x 1 );
my $pattern = 'WVX';

print "\@list has " . @list . " elements!\n";


cmpthese( -2, {
        'grep_eq'   => \&grepped_eq,
        'splice_eq' => \&spliced_eq,
        'grep_re'   => \&grepped_re,
        'splice_re' => \&spliced_re,
} );


sub grepped_eq {
        my @aa = @list;
        @aa = grep { $_ eq $pattern } @aa;
}

sub spliced_eq { 
        my @aa = @list;
        for my $i ( reverse 0 .. $#aa ) {
                splice @aa, $i, 1 if $aa[$i] eq $pattern;
        }
}

sub grepped_re {
        my @aa = @list;
        @aa = grep { m/\Q$pattern\E/ } @aa;
}

sub spliced_re {
        my @aa = @list;
        for my $i ( reverse 0 .. $#aa ) {
                splice @aa, $i, 1 if $aa[$i] =~ m/\Q$pattern\E/;
        }
}

__END__
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Gast Gast
 2008-10-20 15:11
#115653 #115653
Priiiima hat geklappt, danke!

@pq: jups danke für den Hinweis, mache ich normalerweise so :)
<< >> 6 Einträge, 1 Seite



View all threads created 2008-10-20 13:25.