Пользовательский вид массива в жемчуге

У меня есть массив жемчуга к - делают задачи, который похож на это:

@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() из-за тех идентификаторов рядом с задачами, таким образом, я предполагаю, что своего рода специализированная подпрограмма сортировки необходима. Однако мое знание того, как сделать это эффективно в жемчуге, минимально.

Спасибо, все.

6
задан ABach 30 May 2010 в 19:21
поделиться

3 ответа

Похоже, вам нужно преобразование Шварца :

@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;
12
ответ дан 8 December 2019 в 15:59
поделиться

Вот версия, в которой достаточно четко описано, как это работает:

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;
3
ответ дан 8 December 2019 в 15:59
поделиться

Вот исправленное решение @ 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;
0
ответ дан 8 December 2019 в 15:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: