#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. Такое случается редко, но я подумал, что было бы неплохо добавить его 🙂