Thread doppelte Zeilen
(7 answers)
Opened by gmafx at 2010-02-26 16:44
Ich habe dich da irgendwie falsch verstanden, ich dachte du hättest ein zweidimensionales Array:
Code (perl): (dl
)
1 2 3 4 5 6 7 8 my @liste=( \@zeile1, \@zeile2, \@zeile3, \@zeile4, #... \@zeilen ) Code (perl): (dl
)
my $wert=$liste[$ZeilenNr]->[$SpaltenNr] Du sagst nun aber du hast so was: wobei jede Zeile ein String ist. Dann sind die Zeilen ja schon zu einem String zusammengefügt und du kannst die Sache mit dem Unique verweinfachen: 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 46 47 48 49 50 51 52 53 54 # bitte immer strict und warnings nutzen, # du bekommst dann bei vielen Fehlern Meldungen, # die perl ansonsten versuchen würde zu interpretieren. use strict; use warnings; # Dateiname der Datei, # welche die Zeile enthält # wie erstellst du die Datei? # Ich vermute mal, # dass du nicht immer eine Datei erstellen willst # um eindeutige Zeilen zu bekommen, oder? # Das ganze geht definitiv auch ohne Datei my $file='test.tab'; # macht das selbe wie # @liste = `cat test.tab`; open(my $fh,'<',$file) or die("ERROR open $file ($!)"); my @liste=<$fh>; close($fh); # unique ist ein Hash # ein Hash hat die Besonderheit, # dass alle Schlüssel(keys genannt) einzigartig sind, # dh, sie tauchen niemals doppelt auf. # das ist soweit klar? my %uniqe=(); # durchlaufe das Array rückwärts for my $cnt (reverse (0..$#liste)) { # die Zeile die oben ausgelesen wurde my $line=$liste[$cnt]; # entferne die Zeile aus dem Array wenn sie schon einmal gefunden wurde # wenn $line als Schlüssel in %unique schon mal vorgekommen ist ( "if($unique{$line})" ), # dann löschen wir die Zeile aus den Array @liste ( "splice(@liste, $cnt,1)" ) splice(@liste, $cnt,1) if($uniqe{$line}); # nun Zählen wir den Wert, # der zum Schlüssel $line gehört, um 1 hoch $uniqe{$line}++; # man kann hier auch schreiben: # $uniqe{$line}=1; # das gibt die Aktuelle Zeilennummer aus print "$cnt\n"; } # alles testweise ausgeben: for my $line (@liste) { print $line; } 2010-02-26T19:37:28 gmafx Du kennst doch Einen Hash mit Werten: Du kannst nun auch schreiben: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 my $wert=''; my %hash=(); $wert='bla'; $hash{$wert}=1; $wert='foo'; $hash{$wert}=1; $wert='bar'; $hash{$wert}=1; wenn man das schreiben kann kann man auch das schreiben: Code (perl): (dl
)
1 2 3 4 5 6 7 my @liste=('bla','foo','bar'); my %hash=(); for my $wert (@liste) { $hash{$wert}=1; } Soweit klar? Nun benutze ich dies um die Eingelesene Zeile als Schlüssel für den Hash zu benutzen. 2010-02-26T19:37:28 gmafx Ich kann dir nicht folgen? Wie bitte ließt du die Zeilen denn nun?? Erst hast du Arrays und dann nicht?! Machts du so was in der Art? Code (perl): (dl
)
1 2 3 4 5 while(my @line=read_line_von_irgendwo) { my $zeilendaten=join(',',@zeile); push(@liste,$zeilendaten); } Wenn ja, kannst du dir das zusammenfügen sparen indem du eine Referenz auf das Array in @liste tust: 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 my @liste; # ... while( my @line=lese_zeilen_von_irgendwo() ) { my $zeilendaten=join(',',@zeile); push(@liste,[@zeile]; # oder: # push(@liste,\@zeile; } # ... # nun wollen wir nur die Zeilen, die einzigartig sind my %uniqe=(); # durchlaufe das Array rückwärts for my $cnt (reverse (0..$#liste)) { # ein String generieren der "eindeutig" ist my $line=join(',',@{$liste[$cnt]}); # entferne die Zeile aus dem Array wenn sie schon einmal gefunden wurde splice(@liste, $cnt,1) if($uniqe{$line}); # setze diese Zeile als gefunden; $uniqe{$line}++; } for(@liste) { print join(', ',@$_)."\n"; } aber bitte erkläre genauer wo und wie du die Daten ließt? |