Sort in lexicographical order

I see the results from the following code, but I don’t understand how exactly it orknows what to do in the following example sort:

use Data::Dumper;

$animals{'man'}{'name'} = 'paul';
$animals{'man'}{'legs'} = 2;
$animals{'cheeta'}{'name'} = 'mike';
$animals{'cheeta'}{'legs'} = 3;
$animals{'zebra'}{'name'} = 'steve';
$animals{'zebra'}{'legs'} = 4;
$animals{'cat'}{'name'} = '';
$animals{'cat'}{'legs'} = 3;
$animals{'dog'}{'name'} = '';
$animals{'dog'}{'legs'} = 4;
$animals{'rat'}{'name'} = '';
$animals{'rat'}{'legs'} = 5;

@animals = sort {
      $animals{$a}{'name'} cmp $animals{$b}{'name'}
   or $animals{$a}{'legs'} <=> $animals{$b}{'legs'}
} keys %animals;

print Dumper(\@animals);
+3
source share
3 answers

or is a short circuit evaluator, so it returns the value of the left side if it is true (which is any non-zero value), and otherwise it will evaluate the right side.

So, in this case, if the names of the animals are compared as equal, (0 - false), the number of legs will be counted for sorting purposes.

+9
source

( {} 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 , -1 1 - true. cmp , or , sort . cmp false, <=> .

"-" (aka Schwartzian Transform):

@animals =
  map  { $_->[0] }
  sort {
    $a->[1] cmp $b->[1] ||
    $a->[2] <=> $b->[2]
  }
  map { [$_, $animal{$_}{name}, $animal{$_}{legs}] }
  keys %animal;

, , , . , - (, , ) . , , .

+14

Can anyone suggest Sort::Keyan alternative for real code?

use Sort::Key::Multi qw(sikeysort);  # sort keyed on (string, integer)
@animals = sikeysort { $animals{$_}{name}, $animals{$_}{legs} } keys %animals;

# alternately,
use Sort::Key::Maker sort_by_name_then_legs =>
    sub { $animals{$_}{name}, $animals{$_}{legs} }, qw(string integer);
@animals = sort_by_name_then_legs keys %animals;
+2
source

Source: https://habr.com/ru/post/1710715/


All Articles