[英]Custom array sort in perl
我有一個perl待辦事項數組,看起來像這樣:
@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"
);
第一個數字是任務的ID。 如果任務旁邊有([AZ]),則定義任務的優先級。 我想做的是對任務數組進行排序,將優先項放在第一位(並按優先級從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",
);
由於任務旁邊的那些ID,我無法使用常規的sort()
,因此我假設需要某種自定義的排序子例程。 但是,我對如何在Perl中有效執行此操作的了解很少。
謝謝大家
聽起來像您想要施瓦茨變換 :
@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;
更簡單的解決方案:
sort {($a =~ /\((.)\)/)[0] cmp ($b =~ /\((.)\)/)[0]} @todos;
use Sort::Key 'keysort';
my @sorted = keysort { /^\d+\s+\(([A-Z])\)/ ? $1 : 'ZZ' } @todos;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.