/ / Niestandardowe sortowanie tablic w perlu - perl, sortowanie, tablice

Niestandardowe sortowanie tablic w perlu - perl, sortowanie, tablice

Mam tablicę zadań do wykonania, która wygląda następująco:

@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"
);

Ten pierwszy numer to identyfikator zadania. Jeśli zadanie ma ([AZ]) obok, które określa priorytet zadania.Jego chcę zrobić, to posortuj tablice zadań w taki sposób, aby najpierw uporządkować elementy priorytetowe (w kolejności malejącego priorytetu, od A do 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",
);

Nie mogę użyć zwykłego sort() z powodu tych identyfikatorów obok zadań, więc zakładam, że potrzebny jest jakiś niestandardowy podprogram sortowania, ale moja wiedza na temat tego, jak zrobić to skutecznie w perlu jest minimalna.

Dziękuje wszystkim.

Odpowiedzi:

12 dla odpowiedzi № 1

Brzmi, jakbyś chciał Transformacja Schwartzian:

@todos =
map  { $_->[0] }
sort { $a->[1] cmp $b->[1] or $a->[0] cmp $b->[0] }
map  { [ $_, /^d+ (([[:alpha:]]))/ ? $1 : "[" ] }
@todos;

"[" jest znakiem po "Z"; nadanie tego "priorytetu" innym pozycjom niepriorytetycznym spowoduje ich sortowanie po priorytetowych pozycjach.

Alternatywnie i być może łatwiejsze do uchwycenia:

@todos =
map { substr $_, 1 }
sort
map { (/^d+ (([[:alpha:]]))/ ? $1 : "[") . $_ }
@todos;

3 dla odpowiedzi № 2

Oto wersja, która jest dość jednoznaczna o tym, jak to działa:

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 dla odpowiedzi № 3

Tutaj jest naprawiony Rozwiązanie @Sean który używa sortowania numerycznego dla identyfikatorów zadań (w ten sposób 10 zadanie idzie po 9, tak jak powinno):

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 dla odpowiedzi nr 4
use Sort::Key "keysort";

my @sorted = keysort { /^d+s+(([A-Z]))/ ? $1 : "ZZ" } @todos;

0 dla odpowiedzi № 5

Znacznie prostsze rozwiązanie:

sort {($a =~ /((.))/)[0] cmp ($b =~ /((.))/)[0]} @todos;