В Perl, как я могу отсортировать ключи хеша, используя пользовательский порядок? - PullRequest
4 голосов
/ 17 ноября 2011

Я пытаюсь выполнить работу с хэшем файлов, и работа должна выполняться в определенном порядке.Большинство скажет, что список можно упорядочить так:

for my $k (sort keys %my_hash)
{
    print "$k=>$my_hash{$k}, ";
}

Однако мне нужен неалфавитный порядок, ведь ключи начинаются со слова, а затем _ и идут от G до digits доL к любому из M,P,R,T or D (например, word_G.txt, word_2.txt, ..., word_P.txt).Есть ли способ сортировки по индивидуальному заказу?

Ответы [ 3 ]

12 голосов
/ 17 ноября 2011

Есть ли способ сортировки по индивидуальному заказу?

Да. См сортировка .

Например:

#!/usr/bin/env perl

use warnings; use strict;

my @order = qw(G 1 2 3 L M P R T D);

my %order_map = map { $order[$_] => $_ } 0 .. $#order;

my $pat = join '|', @order;

my @input = qw(word_P.txt word_2.txt word_G.txt);

my @sorted = sort {
    my ($x, $y) = map /^word_($pat)[.]txt\z/, $a, $b;
    $order_map{$x} <=> $order_map{$y}
} @input;

print "@sorted\n";
4 голосов
/ 17 ноября 2011
use 5.014;

sub rank {
    my ($word) = @_;
    $word =~ s{\A \w+ _}{}msx;
    return do {
        given ($word) {
            0 when /\A G/msx;
            1 when /\A [0-9]/msx;
            2 when /\A L/msx;
            3 when /\A [MPRTD]/msx;
            default { 1000 };
        }
    };
}

say for sort { rank($a) <=> rank($b) } qw(word_P.txt word_2.txt word_G.txt);

Выход:

word_G.txt
word_2.txt
word_P.txt

Редактировать: до Perl 5.14 использовать временную переменную.

use 5.010;
⋮
return do {
    my $dummy;
    given ($word) {
        $dummy = 0 when /\A G/msx;
        $dummy = 1 when /\A [0-9]/msx;
        $dummy = 2 when /\A L/msx;
        $dummy = 3 when /\A [MPRTD]/msx;
        default { $dummy = 1000 };
    }
    $dummy;
};
0 голосов
/ 08 февраля 2018

У меня был конкретный вариант использования, когда я хотел сначала отсортировать по определенным значениям, потом другие значения, а затем по всему алфавиту посередине.

Вот мое решение:

my @sorted = sort {
    my @order = qw(Mike Dave - Tom Joe);
    my ($x,$y) = (undef,undef);
    for (my $i = 0; $i <= $#order; $i++) {
        my $token = $order[$i];
        $x = $i if ($token eq $a or (not defined $x and $token eq "-"));
        $y = $i if ($token eq $b or (not defined $y and $token eq "-"));
    }
    $x <=> $y or
    $a cmp $b
} @ARGV;

Выход:

$ perl customsort.pl Tom Z Mike A Joe X Dave G
Mike Dave A G X Z Tom Joe
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...