Sortsub (материал в {}
после sort
) определяет двухуровневую сортировку: сначала по имени, а затем по количеству ветвей. or
реализует перекрестный переход между двумя критериями. Проще увидеть, если вы отформатируете код по-другому:
@animals = sort {
$animals{$a}{'name'} cmp $animals{$b}{'name'} or
$animals{$a}{'legs'} <=> $animals{$b}{'legs'}
} keys %animals;
Операторы cmp
и <=>
возвращают одно из трех значений (-1, 0 или 1) в зависимости от того, является ли левый аргумент меньше, равен или больше правого аргумента. (cmp
выполняет сравнение строк, <=>
- числовое.) В Perl 0 равно false, а -1 и 1 - true. Если cmp
возвращает истинное значение, or
немедленно возвращает это значение, и sort
соответствующим образом переупорядочивает элементы. Если cmp
возвращает false, <=>
оценивается и вместо него возвращается его результат.
При выполнении многослойных сортировок обычно используется метод "map-sort-map" (a.k.a. Преобразование Шварца ):
@animals =
map { $_->[0] }
sort {
$a->[1] cmp $b->[1] ||
$a->[2] <=> $b->[2]
}
map { [$_, $animal{$_}{name}, $animal{$_}{legs}] }
keys %animal;
Это не так ясно, но, поскольку он обычно имеет лучшую производительность, это обычная идиома. Это особенно важно, когда операнды сравнения являются функциями - этот метод предотвращает ненужный (и, возможно, дорогой) пересчет для каждого сравнения. Например, если вы сортируете строки по длине, вам нужно вычислить длину каждой строки только один раз.