Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
Hallo, ich hoffe das hier ein Perlexperte gibt der mir helfen kann. ich habe ein mehrdimensionales array der so aussieht (ungefähr). @Z=('arno', 'bert' , '3', 'dino' ) ('emil', 'franz' , '1', 'gert' ) ('hans'), ' ' , '2' , ' ' ) wie könnte ich Zeilen sortieren nach der Dritten Spalte?
Datum: 19.03.2007-15:10

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
my @AoA = ( ['arno', 'bert', '3', 'dino'], ['emil', 'franz', '1', 'gert'], ['hans', '', '2', ''] );my $SPALTE = 3; my @AoA_sorted = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @AoA;
oder so ungefähr ;)
Datum: 19.03.2007-15:45

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
ich danke dir , ich werde es probieren
Datum: 19.03.2007-16:10

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| Es ht leider nicht funktioniert aber hier ist der Code vielleicht hast du eine Idee woran es liegt. my $i; my @inhaltSteps={}; my @tempArray;my @sortedsteps; for ($i=0; $i<$CountSteps;$i++) { @checkedSteps=StandLib::GetALLNodeValues('Steps',$i); for (my $j=0;$j<@checkedSteps;$j++) { $tempArray[$i][$j]=@checkedSteps[$j]; # Wichtige Spalte zum sortieren @inhaltSteps=$tempArray[$i][5]; # Inhalt der Spalte wird ausgegeben print @inhaltSteps; #@sortedsteps = join(", ", sort{&sortNumbers2}(@inhaltSteps))."\n"; } } my $SPALTE = $tempArray[$i][5]; my @tempArray = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @tempArray; print @tempArray;
Datum: 19.03.2007-16:40

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
upps.. da wären so einige Fehler. $tempArray[$i][$j]=@checkedSteps[$j];
das mag zwar funktionieren ist aber syntaktisch nicht korrekt
$tempArray[$i][$j]=$checkedSteps[$j];
Wenn du 'warnings' einbindest bekommst du auch eine entsprechende Warnmeldung
#!/usr/bin/perl use warnings; my @array = qw(aaa bbb ccc ddd eee); print @array[3];
Scalar value @array[3] better written as $array[3] at temp.pl line 7.
@inhaltSteps=$tempArray[$i][5];
hier weist du einen einzelnen Wert einer Liste zu, ist vielleicht so nicht gewünscht, denn die @inhaltSteps enthält für den Moment nur noch einen einzelnen Wert. my $SPALTE = $tempArray[$i][5];
Hier uebergibst du den Inhalt von $tempArray[$i][5] an $SPALTE, das war von mir anders vorgesehen:
my $SPALTE = 6;@tempArray = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @tempArray; print @tempArray;
im sort-Codeblock passiert nun folgendes
$a->[6 - 1] <=> $b->[6 - 1]bzw. $a->[5] <=> $b->[5]
es werden jeweils das sechste Element (Spalte) der anonymen Arrays von @tempArray miteinander nummerisch verglichen.Für weitere Hilfe wäre wichtig zu wissen welche Datenstruktur StandLib::GetALLNodeValues() zurückgibt. Eine Liste von Skalaren, Liste von Arrays, ... ? upps.. da wären so einige Fehler.[code] $tempArray[$i][$j]=@checkedSteps[$j];
das mag zwar funktionieren ist aber syntaktisch nicht korrekt
$tempArray[$i][$j]=$checkedSteps[$j];
Wenn du 'warnings' einbindest bekommst du auch eine entsprechende Warnmeldung
#!/usr/bin/perl use warnings; my @array = qw(aaa bbb ccc ddd eee); print @array[3];
Scalar value @array[3] better written as $array[3] at temp.pl line 7.
@inhaltSteps=$tempArray[$i][5];
hier weist du einen einzelnen Wert einer Liste zu, ist vielleicht so nicht gewünscht, denn die @inhaltSteps enthält für den Moment nur noch einen einzelnen Wert. my $SPALTE = $tempArray[$i][5];
Hier uebergibst du den Inhalt von $tempArray[$i][5] an $SPALTE, das war von mir anders vorgesehen:
my $SPALTE = 6;@tempArray = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @tempArray; print @tempArray;
im sort-Codeblock passiert nun folgendes
$a->[6 - 1] <=> $b->[6 - 1]bzw. $a->[5] <=> $b->[5]
es werden jeweils das sechste Element (Spalte) der anonymen Arrays von @tempArray miteinander nummerisch verglichen.Für weitere Hilfe wäre wichtig zu wissen welche Datenstruktur StandLib::GetALLNodeValues() zurückgibt. Eine Liste von Skalaren, Liste von Arrays, ... ?
Datum: 19.03.2007-18:15

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| Mehrere Codebeispiele Methode I:
for(my $i = 0; $i < $CountSteps; $i++) { my @checkedSteps = StandLib::GetALLNodeValues('Steps', $i); for( my $j = 0; $j < scalar(@checkedSteps); $j++) { $tempArray[$i][$j] = $checkedSteps[$j]; } } my $SPALTE = 6; my @tempArray = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @tempArray; use Data::Dumper; print Dumper(\@tempArray);
Methode II:
for(my $i = 0; $i < $CountSteps; $i++) { my @checkedSteps = StandLib::GetALLNodeValues('Steps', $i); $tempArray[$i] = \@checkedSteps; } my $SPALTE = 6; my @tempArray = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @tempArray; use Data::Dumper; print Dumper(\@tempArray);
Methode III:
for(my $i = 0; $i < $CountSteps; $i++) { my @checkedSteps = StandLib::GetALLNodeValues('Steps', $i); $tempArray[$i] = [ @checkedSteps ]; } my $SPALTE = 6; my @tempArray = sort { $a->[$SPALTE - 1] <=> $b->[$SPALTE - 1]} @tempArray; use Data::Dumper; print Dumper(\@tempArray);
Bitte verwende zum Posten von Code die 'code'-Tags.
Datum: 19.03.2007-18:39

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
Ich danke dir für deine Erklärung Wunderbar, deine 3 Methoden funktionieren und zwar sehr gut. hier habe ich auch eine gebastelt und die hat auch funktioniert wie es sein soll.( ausgabe siehe unten, mit deinen Methoden sieht es fast gleich aus).soweit so gut jetzt aber versuche ich erstmal nach Typ(Run, MD,md,copy,shortcut..) sortieren dann nach steps. wenn du wieser eine idee hast ;) und ich danke dir für diene Erklärung nochmal ######## my $i; my @inhaltSteps={}; my @tempArray; my @sortedsteps; for ($i=0; $i<$CountSteps;$i++) { @checkedSteps=StandLib::GetALLNodeValues('Steps',$i); for (my $j=0;$j<@checkedSteps;$j++) { $tempArray[$i][$j]=@checkedSteps[$j]; @inhaltSteps=$tempArray[$i][5]; # Wichtige Spalte zum sortieren #print $tempArray[$i][$j]; # #print @inhaltSteps; # Inhalt der Spalte wird ausgegeben } } print join(' - ', @{$_}), "\n" for sort vergl @tempArray; sub vergl { return -1 if $$a[5]<$$b[5]; # 5te Spalte return 1 if $$a[5]>$$b[5]; # 5te Spalte return 0; } ######## Ausgebe sieht so aus: HASH(0x22e65f0) - Run - - - 1 - HASH(0x1830c54) - MD - - C:\Win16App - - 1 - HASH(0x1830ca8) - md - - C:\4711 - - 1 - HASH(0x1830cfc) - Copy - D:\Dev\Null - C:\Dev\Null - - 1 - HASH(0x1830d44) - Copy - D:\temp - C:\Dev\Null - - 1 - HASH(0x1830c6c) - Copy - D:\Dev\Null - C:\Win16App - - 1 - HASH(0x1830cc0) - Copy - D:\temp - C:\Win16App - - 1 - HASH(0x1830d14) - shortcut - - D:\PlatformInstaller\away.lnk - D:\PlatformInstaller\empty.bat - 1 - HASH(0x22e7878) - shortcut - - D:\PlatformInstaller\test.lnk - D:\PlatformInstaller\empty.bat - 1 - HASH(0x1830bd0) - shortcut - - D:\PlatformInstaller\new.lnk - D:\PlatformInstaller\Test.xml - 1 - HASH(0x22e77e8) - shortcut - - D:\PlatformInstaller\test.lnk - D:\PlatformInstaller\Test.xml - 1 - HASH(0x22e7830) - Run - - - C:\totalcmd\totalcmd.exe - 1 - HASH(0x1830c0c) - AdminCheck - - - - 1 - HASH(0x22e6668) - envuser - PITEST - bla - User - 1 - HASH(0x22e66e0) - envuser - PITEST - bli;blub - User - 1 - HASH(0x22e6758) - envsystem - PITEST - bla - System - 1 - HASH(0x22e67d0) - envsystem - PITEST - bli;blub - System - 1 - HASH(0x22e68c0) - EnvSort - PITEST - blub;bli;bla - system - 1 - HASH(0x22e6848) - EnvSort - PITEST - bli;bla;blub - user - 2 - HASH(0x22e7a40) - Run - - - C:\totalcmd\totalcmd.exe - 2 - HASH(0x22e79c8) - Run - - - C:\totalcmd\totalcmd.exe - 3 - HASH(0x22e7b30) - Run - - - C:\totalcmd\totalcmd.exe - 4 - HASH(0x22e7ab8) - Run - - - C:\totalcmd\totalcmd.exe - 5 -
Datum: 20.03.2007-09:58

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
Es hat sich erledigt. jetzt komme auf die idee ich brauche es einfach wie es jetzt ist und es ist ok so. und danke dir nochmal;-)
Datum: 20.03.2007-10:14

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
bitte, bitte... der vollständigkeithalber die Info wie man nach mehreren Spalten sortiert
#!/usr/bin/perl use strict; use warnings; my @arr = ( # Name Vorname Alter [ 'aaa', 'zzz', 27 ], [ 'aaa', 'yyy', 21 ], [ 'aaa', 'zzz', 34 ], [ 'ddd', 'www', 23 ], [ 'eee', 'vvv', 29 ] ); my @arr_sorted = sort { $a->[0] cmp $b->[0] # nach Name || $a->[1] cmp $b->[1] # nach Vorname || $a->[2] <=> $b->[2] # nach Alter } @arr; print "@{$_}\n" for @arr_sorted;
Datum: 20.03.2007-13:47

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
ich brauche wieder deine Hilfe und natürlich wenn du zeit und lust hast. glaubst du das das Program die sortirung nach der sortierung beibehalten wird danach oder nicht?ich möchte das er sortiert nach steps jedes mal wenn irgenwas instaliert wird. ich bin einfach jetzt durcheinander.sub install{ my @key; my $cont = 1; my @timeData = localtime(time); @timeData[4]+=1; @timeData[5]+=1900; open (LOGFH, ">> C:\Installer.log") or die "can't append: $!\n"; print LOGFH "====================\n"; print LOGFH "@timeData[3].@timeData[4].@timeData[5] @timeData[2]:@timeData[1]:@timeData[0]\n"; print LOGFH "====================\n\n"; wird ins LogFile geschrieben if ($cont==1){ @checkedSteps=getSteps(@checkedSteps); Aufruf von getsteps for (my $i=0; $i<$CountSteps; $i++){ print @checkedSteps[$i]; if (@checkedSteps[$i] ne "0"){ if (@checkedSteps[$i] ne @checkedSteps[$i-1]){ #-------------- my @tempArray; for ($i=0; $i<$CountSteps;$i++) { @checkedSteps=StandLib::GetALLNodeValues('Steps',$i); for (my $j=0;$j<@checkedSteps;$j++) { $tempArray[$i][$j]=@checkedSteps[$j]; } } #### my @tempArray_sorted = sort { #$a->[1] cmp $b->[1] #|| $a->[5] <=> $b->[5] } @tempArray; print "@{$_}\n" for @tempArray_sorted; #------------- my $Prog=@checkedSteps[$i]; newProg($Prog); } my @NodeValues = StandLib::GetALLNodeValues('Steps',$i); #---- if (uc(@NodeValues[1]) eq 'COPY'){ if (-e @NodeValues[2]){ if (-e @NodeValues[3]){.....
Datum: 21.03.2007-11:43

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
Würde schon weiterhelfen, komme aber mit deinen Codeausschnitt nicht so recht klar, soll heißen ich weiß nicht genau was er macht. Bin von Anfang an nicht durch deinen Code durchgestiegen, da wahrscheinlich einige Teile zum Verständnis fehlen, bzw. mir die Grundfunktionalität des Scriptes nicht bekannt ist.Vielleicht kannst du das jetzige Problem in einen extra Codestück rekonstruieren (auf die wichtigsten Sachen beschränkt). Oder du erklärst welche Aufgaben dein Script genau erledigt.
Datum: 21.03.2007-20:24

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
ich kann leider Das code nicht veröffentlichen. du kannst mir aber helfen schon wenn du mir sagts wie ich das Mehrdmensionale Array von voher leeren kann.? ;-) und allgemein damit du weisst was mein Ziel ist. ich muss ein InstallPlattform programieren, damit kann man von einem administratorrechner viele Programme,ordner... gelöscht, installiert, copiert... und danke dir sehr viel denn mit deiner Hilfe ist die Arbeit besser geworden.
Datum: 22.03.2007-09:18

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| Mehrdimensionales Array leeren -> http://www.perlunity.de/cgi-bin/forum/forum_thread_linear.cgi?tid=19853&mid=40194&fid=8&pn=0 Wenn du den Code nicht posten kannst, dann versuch in einen kleinen Script den Code auf den sich das Problem bezieht zu rekonstruieren.
Datum: 22.03.2007-18:44

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
Das Teil ist jetzt fertig, funktioniert jetzt Fehlerfrei. ich probiere jetzt mal das ArrayArray zu leeren denn das brauche ich für eine andere Funktion. und danke dir nochmal (jetzt bistdu wie mein Betreuer) ;)
Datum: 23.03.2007-09:36

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| ascheinend ist das array nicht gelehrt?? weisst du vielleicht warum? #------Das ist ein Teil meines Scriptes--- use StandLib; use strict; #use warnings; use Tk; use Win32::Registry; use Win32::TieRegistry; use Data::Dumper; for (my $i=0; $i<$CountSteps; $i++) { if (@checkedSteps[$i] ne "0"){ my @NodeValues = StandLib::GetALLNodeValues('Steps',$i+1); if (@checkedSteps[$i] ne @checkedSteps[$i-1]) { $x=0; for (my $y=0;$y<@NodeValues;$y++) { $tempArray[$x][$y]=@NodeValues[$y]; #print "@{$_}\n" for @tempArray; } #----------------------------- my $Prog=@checkedSteps[$i]; newProg($Prog); } else{ $x++; for (my $y=0;$y<@NodeValues;$y++) { $tempArray[$x][$y]=@NodeValues[$y]; } } my @tempArray_sorted = sort { $a->[5] <=> $b->[5] } @tempArray; @tempArray = @tempArray_sorted; # Aufruf von Subroutine_Funktion } } print "@{$_}\n" for @tempArray; print"\n" #---Mehrdimensionale @tempArray Leeren--- foreach my $arrRef (@tempArray) { $_ = 0 for @{$arrRef}; } print Dumper \@tempArray; }
Datum: 23.03.2007-10:19

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
print "@{$_}\n" for @tempArray; print"\n" #---Mehrdimensionale @tempArray Leeren--- foreach my $arrRef (@tempArray) { $_ = 0 for @{$arrRef}; } print Dumper \@tempArray; }
hinter »print "\n"« fehlt das Semikolon. Das Script sollte sich also nicht ausführen lassen - wegen Syntaxerror (event. ist auch der Code nicht vollständig). Jedenfalls konnte ich keinen anderen Fehler finden, habe die Variablen mit Dummydaten gefüllt und damit werden die Arrays genullt. #!/usr/bin/perl# use StandLib; use strict; use warnings; use Tk; use Win32::Registry; use Win32::TieRegistry; use Data::Dumper; my @checkedSteps = qw(zzz yyy xxx www vvv uuu); my $CountSteps = 5; my $x = 0; my @tempArray; for (my $i=0; $i < $CountSteps; $i++) { if ($checkedSteps[$i] ne "0") { #my @NodeValues = StandLib::GetALLNodeValues('Steps',$i + 1); my @NodeValues = (map {"$_$i"} qw(aaa bbb ddd eee fff ggg)); if ($checkedSteps[$i] ne $checkedSteps[$i-1]) { $x = 0; for (my $y = 0; $y < @NodeValues; $y++) { $tempArray[$x][$y] = $NodeValues[$y]; print "@{$_}\n" for @tempArray; } #----------------------------- my $Prog = $checkedSteps[$i]; #newProg($Prog); } else { $x++; for (my $y = 0; $y < @NodeValues; $y++) { $tempArray[$x][$y] = $NodeValues[$y]; } } my @tempArray_sorted = sort { $a->[5] <=> $b->[5] } @tempArray; @tempArray = @tempArray_sorted; # Aufruf von Subroutine_Funktion } } print "@{$_}\n" for @tempArray; print"\n"; #---Mehrdimensionale @tempArray Leeren--- foreach my $arrRef (@tempArray) { $_ = 0 for @{$arrRef}; } print Dumper \@tempArray;
PS: Du solltest nicht warnings auskommentieren, korrigiere lieber den Code so dass die Warnungen nicht mehr kommen. Glaub mir, dass kann dir in vielen Fällen Zeit sparen wenn es darum geht einen Fehler im Code zu finden.
Datum: 24.03.2007-18:47

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| du hast recht mit den warnings. nur halt stehe ich unter Zeitdruck. Ich mache das später( die warnings zu beseitigen).Danke für dein Tip und glaube mir das werde ich machen
Datum: 26.03.2007-12:36

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| endlich habe die warnings beseitigt das war schon eine menge ;-)
Datum: 26.03.2007-14:33

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
ich möchte das @tempArray ( Mehrdimensional) übergeben ( an sub Routine) wie könnte ich bitte das machen?wie geht das? hier hast du das code. my @NodeValues = StandLib::GetALLNodeValues('Steps',$i+1); if (@checkedSteps[$i] ne @checkedSteps[$i-1]) { #-------------- $x=0; for (my $y=0;$y<@NodeValues;$y++) { $tempArray[$x][$y]=@NodeValues[$y]; } #------------- #----------------------------- my $Prog=@checkedSteps[$i]; newProg($Prog); # neues Program } else { $x++; for (my $y=0;$y<@NodeValues;$y++) { $tempArray[$x][$y]=@NodeValues[$y]; # for (my $y=0;$y<@NodeValues;$y++) # # 1 } } my @tempArray_sorted = sort { $a->[5] <=> $b->[5] # sortieren nach 5te Spalte (Step) } @tempArray; @tempArray = @tempArray_sorted; #print @tempArray; &Subroutine(); # Aufruf von Subroutine_Funktion sub Subroutine { #---------- Copy if (uc(@NodeValues[1]) eq 'COPY') { if (-e @NodeValues[2]) { if (-e @NodeValues[3]) { if (!Exists($tl)) { my $cont=0; $tl = $mw->Toplevel(-title => "Warning"); my $label = $tl->Label(-text => ("@NodeValues[3] already exists!\nDo you want to continue?"))->pack(); my $yes =$tl->Button(-text =>"Yes",-command =>sub { $tl->destroy; $cont=1})->pack(-side => 'left'); my $no =$tl->Button(-text =>"No",-command =>sub { $tl->destroy; $cont=0})->pack(-side => 'right'); $tl->waitWindow; if ($cont==1) { system("xcopy ", @NodeValues[2], " ", @NodeValues[3], " /E /I /Y"); Stepdone(@NodeValues[1]); } if ($cont==0) { #... } } else { $tl->deiconify(); $tl->raise(); } } else { #... } } else { if (!Exists($tl)) { $tl = $mw->Toplevel(-title => "Error"); my $close =$tl->Button(-text =>"Close",-command =>sub { $tl->destroy; })->pack(); $tl->waitWindow; Stepfailed(@NodeValues[1]); } else { $tl->deiconify(); $tl->raise(); } } } #------------- elsif (uc(@NodeValues[1]) eq 'MD') { if (-e @NodeValues[3]) { if (!Exists($tl)) { $tl = $mw->Toplevel(-title => "Error"); my $close =$tl->Button(-text =>"Close",-command =>sub { $tl->destroy })->pack(); $tl->waitWindow; Stepfailed(@NodeValues[1]); } else { $tl->deiconify(); $tl->raise(); } } #... } #............. #elsif(.....) #{ ..... #} ....
Datum: 27.03.2007-16:01

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
# als Referenz uebergeben &Subroutine(\@tempArray); # oder # als Kopie uebergeben &Subroutine(@tempArray); # Arbeiten mit der Kopie sub Subroutine { my(@arr) = @_; # @arr enthaelt das gleiche wie @tempArray } # Arbeiten mit der Referenz sub Subroutine { # my($ref) = @_; # oder my $ref = shift; # $ref enthaelt eine Referenz auf @tempArray $ref->[0]->[0]; # entspricht $tempArray[0]->[0]; # Dereferenzieren my @arr = @{$ref}; # @arr enthaelt nun wieder eine Kopie von @tempArray }
Dieses Thema lässt sich nicht auf die Schneller erklären, es gibt viele Möglichkeiten Daten / Variablen an eine Subroutine zu übergeben und mit diesen zu arbeiten. Da ist es besser einen Blick in die Perl-Dokumentation zu werfen.
Datum: 28.03.2007-03:29

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| ich habe es mit sowas versucht und leider ist das @arr nicht mehr schön sortiert wie früher und enthält nicht das gleiche. weisst du warum?und ich hoffe dass ich dich nicht viel störe.Aber ich muss das diese Woche hinkrigen und ich glaube das schaffe ich nicht aber mit deiner Hilfe God sei Dank komme ich immer weiter. Danke dir vielmals #........... #......... &Subroutine(@tempArray); sub Subroutine { my(@arr) = @_; my $x=0; for (my $y=0;$y<@arr;$y++) { $arr[$x][$y]=@_; } print "@{$_}\n" for @arr; ..... }
Datum: 28.03.2007-10:16

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
| es ist ok erledigt ar ein versehen von mir
Datum: 28.03.2007-10:26

|
re: Mehrdimensionales Array sortieren nach Spalten
|
Seitenanfang |
wunderbar funktioniert wie gewollt. danke dir ;-)
Datum: 28.03.2007-15:23

|