Fieser sort
Karle
- perl
1 Christian Kruse0 Karle
0 hotti0 Karle
1 Alexander (HH)0 Karle
Hi,
ich hab hier einen fiesen sort vor mir und bekomme es nicht hin.
Ausgangslage ist ein ein HoA.
<key>: value1 value2 ...
a: name1 neuername1/12
b: name1 neuername2/23
c: name1 neuername1/1
d: name10 neuername1/1
e: name2 neuername1/3
So und nun hätte ich das gerne so sortiert bzw. meinen print:
name1 neuername1/1 ...
name1 neuername1/12 ...
name1 neuername2/23 ...
name2 neuername1/3 ...
name10 neuername1/1 ...
Also die Sortierreihenfolge ist - erst value1 alphabetisch(und wenn möglich die Zahl numerisch) und dann value2 ebenfalls so. Der Key ist mir egal.
Ich hab mir als Anregung http://perldoc.perl.org/perldsc.html#Access-and-Printing-of-a-HASH-OF-ARRAYS angeschaut, aber verstehe es schlicht nicht bzw. kann es nicht umsetzen für meinen Fall.
Gruss
Karle
你好 Karle,
<key>: value1 value2 ...
a: name1 neuername1/12
b: name1 neuername2/23
c: name1 neuername1/1
d: name10 neuername1/1
e: name2 neuername1/3
>
> So und nun hätte ich das gerne so sortiert bzw. meinen print:
>
> ~~~perl
name1 neuername1/1 ...
> name1 neuername1/12 ...
> name1 neuername2/23 ...
> name2 neuername1/3 ...
> name10 neuername1/1 ...
Also die Sortierreihenfolge ist - erst value1 alphabetisch(und wenn möglich die Zahl numerisch) und dann value2 ebenfalls so. Der Key ist mir egal.
Da sort einen Block als Sortier-Kriterium erlaubt, kannst du das doch mit beliebig komplexem Code umsetzen. Ein Ansatz wäre:
use strict;
use Data::Dumper;
sub get_parts;
my $data = {
a => ['name1', 'neuername1/12'],
b => ['name1', 'neuername2/23'],
c => ['name1', 'neuername1/1'],
d => ['name10', 'neuername1/1'],
e => ['name2', 'neuername1/3']
};
my @sorted_keys = sort {
my ($charpart_a,$digitpart_a) = get_parts($data->{$a}->[0]);
my ($charpart_b,$digitpart_b) = get_parts($data->{$b}->[0]);
if($charpart_a eq $charpart_b) {
if($digitpart_a == $digitpart_b) {
my ($charpart_a,$digitpart_a,$digitpart2_a) = get_parts($data->{$a}->[1]);
my ($charpart_b,$digitpart_b,$digitpart2_b) = get_parts($data->{$b}->[1]);
if($charpart_a eq $charpart_b) {
if($digitpart_a == $digitpart_b) {
$digitpart2_a <=> $digitpart2_b;
}
else {
$digitpart_a <=> $digitpart_b;
}
}
else {
$charpart_a cmp $charpart_b;
}
}
else {
$digitpart_a <=> $digitpart_b;
}
}
else {
$charpart_a cmp $charpart_b;
}
} keys %$data;
print join(", ",@sorted_keys),"\n";
sub get_parts {
$_[0] =~ /^(\w+)(\d+)(?:\/(\d+))?$/;
return ($1,int($2),$3);
}
# eof
再见,
克里斯蒂安
Hi,
Danke für den Post ... ich muss da erstmal versuchen durchzublicken was du da machst - aber bin dran, zwar langsam, aber immerhin.
Hab auch noch ne weitere Schwierigkeit entdeckt. Es gibt auch neuername12 (also ohne /Zahl) als value 2. Ohjee.
gruss
Karle
你好 Karle,
Danke für den Post ... ich muss da erstmal versuchen durchzublicken was du da machst - aber bin dran, zwar langsam, aber immerhin.
Wenn du Fragen hast – schiess los.
Hab auch noch ne weitere Schwierigkeit entdeckt. Es gibt auch neuername12 (also ohne /Zahl) als value 2. Ohjee.
In dem Fall spucht der Algorithmus zwar ein paar Warnungen wegen uninitialisierter Werte aus, aber nimmt 0 an für /Zahl. Du müsstest halt $digitpart2_a und $digitpart2_b prüfen und ggfls. mit 0 belegen, um die Warnungen abzuschalten.
再见,
克里斯蒂安
Hi,
ich hab hier einen fiesen sort vor mir und bekomme es nicht hin.
Ausgangslage ist ein ein HoA.
<key>: value1 value2 ...
a: name1 neuername1/12
b: name1 neuername2/23
c: name1 neuername1/1
d: name10 neuername1/1
e: name2 neuername1/3
Hast Du die Möglichkeit, in das Array noch eine Nummer einzutragen, welche die Reihenfolge bestimmt?
Hotte
--
Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
Hi,
»»
»» ich hab hier einen fiesen sort vor mir und bekomme es nicht hin.
»» Ausgangslage ist ein ein HoA.
»»
»» ~~~perl
<key>: value1 value2 ...
»» a: name1 neuername1/12
»» b: name1 neuername2/23
»» c: name1 neuername1/1
»» d: name10 neuername1/1
»» e: name2 neuername1/3
>
> Hast Du die Möglichkeit, in das Array noch eine Nummer einzutragen, welche die Reihenfolge bestimmt?
>
> Hotte
Klar, könnte ich machen -> aber vorher müsste ich diese ermitteln und stehe dann wiede vor dem selben Problem :)
Karle
Moin Moin!
Zum Thema "natural sort" gibt's bei http://perlmonks.org/ diverse Threads, bei CPAN einige Module (Sort::Naturally, Sort::Key::Natural, Data::Sorting).
Alexander
Moin Moin!
Zum Thema "natural sort" gibt's bei http://perlmonks.org/ diverse Threads, bei CPAN einige Module (Sort::Naturally, Sort::Key::Natural, Data::Sorting).
Alexander
Also ich hab die Beispiele gesehen mit Arrays, aber wie mache ich das mit meinem HoA?
So sortiere ich mit dem normalen sort derzeit
foreach my $key ( sort { $ref_hoa_data->{$b}->[0] cmp $ref_hoa_data->{$a}->[0] } keys %$ref_hoa_data )
Nun bekomme ich die Syntax nicht hin für z.B. den nsort des moduls sort::naturally, der ja mein Problem lösen sollte (zumindest mal für das erste Feld.
Gruss
Karle