Сортировка хэша по значению и ключу (в таком порядке)

#perl #sorting #hash

#perl #сортировка #хэш

Вопрос:

Я ищу хороший способ сортировки хэша в Perl сначала по значению, а затем по ключу.

Пример:

  my %userids = (
  williams => "Marketing",
  smith    => "Research",
  johnson  => "Research",
  jones    => "Marketing",
  brown    => "Marketing",
  davis    => "Research"
);
  

Вывод:

 Marketing: brown
Marketing: jones
Marketing: williams
Research: davis
Research: johnson
Research: smith
  

Обратите внимание, что значение было первым уровнем сортировки. Второй уровень сортировки — ключевой. Есть идеи, как сделать это элегантным и высокопроизводительным способом? Спасибо!

Ответ №1:

Хорошая ссылка: http://www.misc-perl-info.com/perl-sort.html#shv

 #!/usr/bin/perl

my %userids = (
    williams => "Marketing",
    smith    => "Research",
    johnson  => "Research",
    jones    => "Marketing",
    brown    => "Marketing",
    davis    => "Research"
);

foreach (sort { ($userids{$a} cmp $userids{$b}) || ($a cmp $b) } keys %userids) 
{
    print "$_: $userids{$_}n";
}
  

Ответ №2:

Я хотел бы добавить еще одну вещь, использовать L sequence при сортировке.

Из Perlfaq4: как мне отсортировать хэш (необязательно по значению вместо ключа)?

Чтобы сделать наш порядок отчетов нечувствительным к регистру, мы используем строку L sequence в двойных кавычках, чтобы все было в нижнем регистре. Затем sort() блок сравнивает значения в нижнем регистре, чтобы определить, в каком порядке размещать ключи.

 foreach (sort { $userids{$a} cmp $userids{$b} or "L$a" cmp "L$b" )  {
    print "$_: $userids{$_}n"; 
} 
  

Вывод :

 brown: Marketing
jones: Marketing
williams: Marketing
davis: Research
Johnson: Research # here 'J'ohnson, J is in uppercase(taking assumption), come as fifth record
smith: Research
  

2.

 foreach (sort { $userids{$a} cmp $userids{$b} or $a cmp $b )  {
    print "$_: $userids{$_}n"; 
}
  

Вывод:

 brown: Marketing
jones: Marketing
williams: Marketing
Johnson: Research # here it shifted to fourth record
davis: Research
smith: Research
  

Комментарии:

1. Я бы сказал, что семантически это будет иметь смысл только при вводе элементов в хэш. В противном случае вы получите необъяснимые результаты, когда хэш содержит как Johnson, так и johnson. Т.Е. При сортировке вы вряд ли можете пойти и сказать «ключи эквивалентны» — по традиционному определению, хэш-таблицы не могут содержать два эквивалентных ключа

2. да, это правда, ключи всегда будут уникальными в хэше, никогда не содержат двух эквивалентных ключей, но вы можете увидеть разницу в выводе.

3. Я вижу разницу в выводе. Вот почему я думаю, что это было бы странно: на мой взгляд, это нарушает принцип наименьшего удивления

4. Такое случается редко, но я подумал, что было бы неплохо добавить его 🙂