Mám perlové pole úloh, ktoré vyzerajú takto:
@todos = (
"1 (A) Complete online final @evm4700 t:2010-06-02",
"3 Write thank-you t:2010-06-10",
"4 (B) Clean t:2010-05-30",
"5 Donate to LSF t:2010-06-02",
"6 (A) t:2010-05-30 Pick up dry cleaning",
"2 (C) Call Chris Johnson t:2010-06-01"
);
Toto prvé číslo je identifikátor úlohy. Ak má úloha ([AZ]) vedľa, ktorá definuje prioritu úlohy, chcem urobiť zoradiť pole úloh spôsobom, ktorý najprv položí prioritné položky (a v poradí zostupnej priority z A - Z):
@todos = (
"1 (A) Complete online final @evm4700 t:2010-06-02",
"6 (A) t:2010-05-30 Pick up dry cleaning",
"4 (B) Clean t:2010-05-30",
"2 (C) Call Chris Johnson t:2010-06-01"
"3 Write thank-you t:2010-06-10",
"5 Donate to LSF t:2010-06-02",
);
Nemôžem používať pravidelné sort()
pretože tieto identifikátory vedľa úloh, tak som predpokladal, že je potrebný nejaký prispôsobený podprogram triedenia, ale moje vedomosti, ako to urobiť efektívne v perl je minimálne.
Ďakujem všetkým.
odpovede:
12 pre odpoveď č. 1Zdá sa, že chcete Schwartzovská transformácia:
@todos =
map { $_->[0] }
sort { $a->[1] cmp $b->[1] or $a->[0] cmp $b->[0] }
map { [ $_, /^d+ (([[:alpha:]]))/ ? $1 : "[" ] }
@todos;
"[" je znak po "Z"; priradenie tejto "priority" iným nepriorizovaným položkám ich zoradí po prioritných položkách.
Alternatívne a možno ľahšie pochopiteľné:
@todos =
map { substr $_, 1 }
sort
map { (/^d+ (([[:alpha:]]))/ ? $1 : "[") . $_ }
@todos;
3 pre odpoveď č. 2
Tu je verzia, ktorá je celkom jasná o tom, ako funguje:
my @sorted_todos = sort {
my ($right_prio) = ($b =~ /^d+s+(([A-Z]))/);
return -1 unless defined $right_prio;
my ($left_prio) = ($a =~ /^d+s+(([A-Z]))/);
return 1 unless defined $left_prio;
return $left_prio cmp $right_prio;
} @todos;
0 pre odpoveď č. 3
Tu je pevná @Sean riešenie , ktorý používa numerické triedenie pre úlohy ID (teda 10. úloha ide po 9.)
my @sorted_todos = map { $_->[0] }
sort { $a->[1][1] cmp $b->[1][1] # A
||
$a->[1][0] <=> $b->[1][0] # 1
} map { [ $_, /^(d+) (([[:alpha:]]))/ ? [$1, $2] : [0, "zz"]] } @todos;
0 pre odpoveď č. 4
use Sort::Key "keysort";
my @sorted = keysort { /^d+s+(([A-Z]))/ ? $1 : "ZZ" } @todos;
0 pre odpoveď č. 5
Oveľa jednoduchšie riešenie:
sort {($a =~ /((.))/)[0] cmp ($b =~ /((.))/)[0]} @todos;