簡體   English   中英

Perl中的自定義數組排序

[英]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;

這是固定的@Sean解決方案 ,該解決方案對任務ID使用數字排序(因此,第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;
use Sort::Key 'keysort';

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM