Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]6512[/thread]

Bestimmtes Element im array löschen

Leser: 13


<< |< 1 2 3 >| >> 22 Einträge, 3 Seiten
kerstin
 2004-08-19 11:31
#49385 #49385
User since
2004-08-19
5 Artikel
BenutzerIn
[default_avatar]
Is es in Perl möglich, in einem dynamischen Array ein bestimmtes element zu löschen?
Die Stelle an der das Element ist, steht nicht fest.
snarf
 2004-08-19 11:51
#49386 #49386
User since
2003-08-14
77 Artikel
BenutzerIn
[default_avatar]
Hallo Kerstin,

natürlich geht das ... (mal ein ungetesteter code)

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my $i = 0;                        
my $suchtext = "finde_mich";


# Schleife über das array bis entweder array-ende oder
# $suchtext gefunden

while ($i < scalar(@array) && $array[$i] ne $suchtext)
{ $++ }

# ist der $suchtext gefunden ???
# wenn ja, dann wird das array "gespliced"

if ($array[$i] eq $suchtext)
{ splice(@array, $i, 1) }
else
{ print "sorry - suchtext [$suchtext] ist nicht enthalten\n" }


Die Schleife ermittelt also über die Erhöhung der Indexvariablen $i die Position des Suchtextes - und dann wird an der gefundenen Position das Array um genau 1 Element gespliced.

Hope2Help, Dirk
Taulmarill
 2004-08-19 12:32
#49387 #49387
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
also, ich kann mich ja irren, aber irgendwie sieht das nicht richtig aus.

mein versuch (auch untested):
Code: (dl )
1
2
3
4
my $suchtext = "finde_mich";
for my $i ( reverse 0 .. $#array ) {
splice(@array, $i, 1) if ($array[$i] eq $suchtext);
}
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
snarf
 2004-08-19 12:49
#49388 #49388
User since
2003-08-14
77 Artikel
BenutzerIn
[default_avatar]
... und wenn Du mir noch sagen könntest, was genau da nicht richtig aussieht, könnte ich mir Gedanken machen :)
Taulmarill
 2004-08-19 12:58
#49389 #49389
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
ohne in anspruchnahme auf vollständigkeit oder richtigkeit.

1. was macht $++? sollte das nicht eher $i++ heissen?
2. das if/else konstrukt müsste doch innerhalb der while schleife stehen, oder?
3. unter der annahme, dass ich mit punkt 1 recht habe, fängst du mit dem array element 1 an und nicht mit 0, da vor der if abfrage hochgezählt wird.
4. da beim splice alle elemente nach dem gelöschten "nachrücken", würde dein script bei jedem löschen das nächste element überspringen.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Ronnie
 2004-08-19 13:00
#49390 #49390
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my @items = qw(foo bar buz baz red green yellow blue);
@items = grep {$_ ne 'red'} @items;
print Dumper \@items;

getestet und funktioniert. Du willst ja das Element nur löschen und nicht wissen wo es war, oder?
Crian
 2004-08-19 13:05
#49391 #49391
User since
2003-08-04
5871 Artikel
ModeratorIn
[Homepage]
user image
Wie wärs einfach mit getestetem Code?

Ich hab einen geschrieben mit zwei verschiedenen Methoden zum Entfernen, einmal mit grep, einmal mit splice:

Code: (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 List::Util qw//;

=pod

=head1 FRAGE VON KERSTIN

   Is es in Perl möglich, in einem dynamischen Array ein bestimmtes element zu löschen?
   Die Stelle an der das Element ist, steht nicht fest.

=cut

my @array = List::Util::shuffle ('Zitrone', 'Apfel', 'Birne', 'Kiwi', 'Pflaume', 'Banane');
# Durch shuffle weiß ich nicht, an welcher Stelle Kiwi ist...
print "Vorher:\n";
print "'$_'\n" for @array;

#
# Möglichkeit 1 mit Grep und zwei Arrays:
#

print "Entferne 'Kiwi' ...\n";

my @ohnekiwi = grep {$_ ne 'Kiwi'} @array;

print "Nachher 1:\n";
print "'$_'\n" for @ohnekiwi;

#
# Möglichkeit 2 mit  splice:
#
my $kiwiindex = -1;
for (0..$#array) { $kiwiindex = $_ if $array[$_] eq 'Kiwi' }

if ($kiwiindex >= 0) {
   splice @array, $kiwiindex, 1;
}
else {
   print "'Kiwi' nicht im Array gefunden\n";
}

print "Nachher 1:\n";
print "'$_'\n" for @array;


Ausgabe (2 Läufe):

Code: (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
G:\privat\perl\forum>array_minus_element.pl
Vorher:
'Pflaume'
'Apfel'
'Birne'
'Zitrone'
'Banane'
'Kiwi'
Entferne 'Kiwi' ...
Nachher 1:
'Pflaume'
'Apfel'
'Birne'
'Zitrone'
'Banane'
Nachher 1:
'Pflaume'
'Apfel'
'Birne'
'Zitrone'
'Banane'

G:\privat\perl\forum>array_minus_element.pl
Vorher:
'Banane'
'Zitrone'
'Pflaume'
'Birne'
'Apfel'
'Kiwi'
Entferne 'Kiwi' ...
Nachher 1:
'Banane'
'Zitrone'
'Pflaume'
'Birne'
'Apfel'
Nachher 1:
'Banane'
'Zitrone'
'Pflaume'
'Birne'
'Apfel'

G:\privat\perl\forum>


Edit: Oh, während ich den Code geschrieben habe hat Ronnie auch schon die Idee mit grep gezeigt - schade ;-)

Grep ist an dieser Stelle imho schöner, es sei denn das Array ist sehr groß (es wird ja zumindestes kurzzeitig verdoppelt).\n\n

<!--EDIT|Crian|1092906429-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Taulmarill
 2004-08-19 13:09
#49392 #49392
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
die möglichkeit mit grep ist natürlich noch eleganter.

@Crain: deine splice-lösung funktioniert aber nur, wenn es nur ein element zu löschen gilt. es wird dann immer das letzte gefundene element gelöscht.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Crian
 2004-08-19 13:16
#49393 #49393
User since
2003-08-04
5871 Artikel
ModeratorIn
[Homepage]
user image
[quote=Taulmarill,19.08.2004, 11:09]@Crain: deine splice-lösung funktioniert aber nur, wenn es nur ein element zu löschen gilt. es wird dann immer das letzte gefundene element gelöscht.[/quote]
Ja, so habe ich die Aufgabe auch verstanden. Allerdings besteht dann ein Unterschied zur Grep-Lösung, da dort alle Kiwis gelöscht werden.\n\n

<!--EDIT|Crian|1092907009-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Crian
 2004-08-19 13:20
#49394 #49394
User since
2003-08-04
5871 Artikel
ModeratorIn
[Homepage]
user image
Code: (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
46
47
#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw//;

=pod

=head1 FRAGE VON KERSTIN

Is es in Perl möglich, in einem dynamischen Array ein bestimmtes element zu löschen?
Die Stelle an der das Element ist, steht nicht fest.

=cut

my @array = List::Util::shuffle ('Zitrone', 'Apfel', 'Birne', 'Kiwi', 'Pflaume', 'Banane', 'Kiwi', 'Kiwi');
# Durch shuffle weiß ich nicht, an welcher Stelle Kiwi ist...
print "Vorher:\n";
print "'$_'\n" for @array;

print "Entferne 'Kiwi' ...\n";


#
# Möglichkeit 1 mit Grep und zwei Arrays:
#
my @ohnekiwi = grep {$_ ne 'Kiwi'} @array;


print "Nachher 1:\n";
print "'$_'\n" for @ohnekiwi;

#
# Möglichkeit 2 mit splice:
#
my @kiwiindex;
for (0..$#array) { push @kiwiindex, $_ if $array[$_] eq 'Kiwi' }

if (@kiwiindex) {
splice @array, $_, 1 for reverse @kiwiindex;
}
else {
print "'Kiwi' nicht im Array gefunden\n";
}


print "Nachher 2:\n";
print "'$_'\n" for @array;


Ausgabe

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Vorher:
'Apfel'
'Kiwi'
'Kiwi'
'Zitrone'
'Kiwi'
'Pflaume'
'Birne'
'Banane'
Entferne 'Kiwi' ...
Nachher 1:
'Apfel'
'Zitrone'
'Pflaume'
'Birne'
'Banane'
Nachher 1:
'Apfel'
'Zitrone'
'Pflaume'
'Birne'
'Banane'


Besser?\n\n

<!--EDIT|Crian|1092907352-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
<< |< 1 2 3 >| >> 22 Einträge, 3 Seiten



View all threads created 2004-08-19 11:31.