Обработка хэша perl в отсортированном порядке по ключу - PullRequest
0 голосов
/ 26 октября 2018

У меня есть скрипт Perl, который использует хеш, где содержимое - это UUID, а ключи - это текстовые элементы XML. Текстовые элементы XML разумно сортируются обычным способом.

Когда я обрабатываю каждый элемент, я пишу в файл журнала. Соответствующий код выглядит примерно так:

use 5.016;
open(my $loghandle, '>', 'process.log') or die "Couldn't open logfile";

%XMLhash = (
      'e01af02f-e8e5-476e-a250-e70c3925463a' => '<Form><AUni ws="fr">retirer</AUni></Form>',
      '8187b534-a8c8-4e14-bf0b-1bd9cfada31e' => '<Form><AUni ws="fr">pencher</AUni></Form>',
      '1848c7a2-c2f8-4884-8327-c0f1a9da7a4b' => '<Form><AUni ws="en">repair</AUni></Form>',
      'b36c127c-91b2-41db-96ec-18c172ad9917' => '<Form><AUni ws="fr">fou</AUni></Form>',
      'abb4e9dc-dc66-43b5-951e-e720e21da286' => '<Form><AUni ws="en">four</AUni></Form>',
      '8cf707e6-e0a1-4611-bb28-ff18d2de38db' => '<Form><AUni ws="en">robust</AUni></Form>',
    );

while( my( $guid, $XMLtext ) = each %XMLhash ) {
    my $somestuff = 'What I did', # some process that tells what I did 
    say $loghandle "Text:$XMLtext Guid:$guid I did $somestuff";
    }

И файл журнала, который это производит (возможно различный порядок каждый запуск):

Text:<Form><AUni ws="en">robust</AUni></Form> Guid:8cf707e6-e0a1-4611-bb28-ff18d2de38db I did:What I did
Text:<Form><AUni ws="en">four</AUni></Form> Guid:abb4e9dc-dc66-43b5-951e-e720e21da286 I did:What I did
Text:<Form><AUni ws="fr">retirer</AUni></Form> Guid:e01af02f-e8e5-476e-a250-e70c3925463a I did:What I did
Text:<Form><AUni ws="fr">fou</AUni></Form> Guid:b36c127c-91b2-41db-96ec-18c172ad9917 I did:What I did
Text:<Form><AUni ws="en">repair</AUni></Form> Guid:1848c7a2-c2f8-4884-8327-c0f1a9da7a4b I did:What I did
Text:<Form><AUni ws="fr">pencher</AUni></Form> Guid:8187b534-a8c8-4e14-bf0b-1bd9cfada31e I did:What I did

Я бы хотел, чтобы файл журнала сортировался по тексту XML, т. Е. По ключу хеш-функции.

Я попытался изменить оператор while на:

while( my( $guid, $XMLtext ) = each sort keys %XMLhash ) {

Это дало мне ошибку: «Тип аргумента для каждой ссылки должен быть необязательным hashref или arrayref в ...»

Чтобы иметь отсортированный файл журнала, могу ли я обработать хэш по ключу?

В моей текущей работе я записываю журналы в массив, сортирую этот массив и записываю массив в файл журнала. Это кажется мне неоптимальным.

1 Ответ

0 голосов
/ 26 октября 2018

Не используйте each для этого.Он работает только с хэшами (и массивами в новых Perls).Используйте обычные foreach и сортируйте по значению.

foreach my $key ( sort { $xml{$a} cmp $xml{$b} } keys %xml ) {
  say "$key: $xml{$key}";
}

Вам нужно взять ключи, а затем отсортировать по значениям, потому что именно там находится XML-штука.

Если вы хотите сначала отсортировать по текстовому узлу, а отдельные текстовые узлы - по атрибуту ws, он становится более сложным.

foreach my $key ( map { $_->[0] }
                  sort { $a->[2] cmp $b->[2] || $a->[1] cmp $b->[1] }
                  map { [ $_, $xml{$_} =~ m/"(..)">([^<]+)</ ] } keys %xml
) {
  say "$key: $xml{$key}";
}

В этом случае используется так называемый Преобразование Шварца , которое выполняет дорогостоящую операцию один раз, запоминает результат для сортировки по нему и затем возвращает исходные данные на место.Поскольку ваш фрагмент XML всегда имеет одинаковый формат, можно использовать регулярные выражения для извлечения данных для сортировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...