сортировать числа по цифрам и строки по алфавиту в массиве хэшей perl - PullRequest
3 голосов
/ 28 мая 2020

Это очень простая проблема, но я не могу ее решить. У меня есть массив хешей. Структура данных следующая:

my @unsorted = (
    {
        'key_5' => '14.271 text',
        # ...
    },
    {
        'key_5' => 'text',
        # ...
    },
    {
        'key_5' => '13.271 text',
        # ...
    },
    {
        'key_5' => 'etext',
        # ...
    },
);

Как я могу отсортировать массив на основе key_5 ha sh. Строковую часть следует отсортировать по алфавиту. а если ключ равен number string (формат всегда такой), его следует отсортировать численно (полностью игнорируя строковую часть). Таким образом, результат будет выглядеть так:

my @sorted = (
    {
        'key_5' => 'etext',
        # ...
    },
    {
        'key_5' => 'text',
        # ...
    },
    {
        'key_5' => '13.271 text',
        # ...
    },
    {
        'key_5' => '14.271 text',
        # ...
    },
);

Итак, элементы массива сортируются на основе key_5 элементов ha sh.

Важно: нельзя использовать пакеты perl, которые не поставляются с собственной установкой perl. Используя perl 5,18

1 Ответ

2 голосов
/ 28 мая 2020

Использование Sort :: Key :: Natural :

use Sort::Key::Natural qw( natkeysort );

my @sorted = natkeysort { $_->{key_5} } @unsorted;

Приведенное выше дает следующее из вашего ввода:

[
    {
        'key_5' => '13.271 text'
        # ...
    },
    {
        'key_5' => '14.271 text'
        # ...
    },
    {
        'key_5' => 'etext'
        # ...
    },
    {
        'key_5' => 'text'
        # ...
    },
]

Если этого недостаточно , вы можете использовать следующее:

use Sort::Key::Multi qw( unskeysort );   # uns = (u)nsigned int, (n)umber, (s)tring

my @sorted =
   unskeysort {
      $_->{key_5} =~ /^([0-9.]+)\s+(.*)/s
         ? ( 1, $1, $2 )
         : ( 0, 0, $_->{key_5} )
   }
      @unsorted;
...