У меня есть массив жемчуга к - делают задачи, который похож на это:
@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"
);
То первое число является идентификатором задачи. Если задача имеет ([A-Z]) рядом с, который определяет приоритет задачи. То, что я хочу сделать, является видом массив задач способом, который помещает расположенные по приоритетам объекты сначала (и в порядке убывающего приоритета, от - 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",
);
Я не могу использовать постоянного клиента sort()
из-за тех идентификаторов рядом с задачами, таким образом, я предполагаю, что своего рода специализированная подпрограмма сортировки необходима. Однако мое знание того, как сделать это эффективно в жемчуге, минимально.
Спасибо, все.
Похоже, вам нужно преобразование Шварца :
@todos =
map { $_->[0] }
sort { $a->[1] cmp $b->[1] or $a->[0] cmp $b->[0] }
map { [ $_, /^\d+ \(([[:alpha:]])\)/ ? $1 : "[" ] }
@todos;
"[ "- это символ после" Z "; предоставление этого «приоритета» элементам, не имеющим приоритета, будет отсортировать их после элементов с приоритетом.
С другой стороны, что, возможно, будет легче понять:
@todos =
map { substr $_, 1 }
sort
map { (/^\d+ \(([[:alpha:]])\)/ ? $1 : "[") . $_ }
@todos;
Вот версия, в которой достаточно четко описано, как это работает:
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;
Вот исправленное решение @ Sean , которое использует числовую сортировку для идентификаторов задач (таким образом, 10-я задача идет после 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;