Reputation: 1434
I would like to sort an array and put particular element to the beginning.
Here is my code:
sub MySort {
my $P = 'node';
if ($a eq $P) {
return -1;
}
return -1 if $a lt $b;
return 0 if $a eq $b;
return 1 if $a gt $b;
}
my @x = qw (abc def xxx yyy ggg mmm node);
print join "\n",sort MySort @x
I expect "node" go to the beginning but it's not working.
Result:
abc
def
ggg
node
mmm
xxx
yyy
Expected Result:
node
abc
def
ggg
mmm
xxx
yyy
Upvotes: 2
Views: 238
Reputation: 1338
You missed the cases when $b
is node
.
sub MySort {
my $P = 'node';
return 0 if $a eq $P && $b eq $P;
return -1 if $a eq $P;
return +1 if $b eq $P;
return $a cmp $b;
}
my @x = qw (abc def xxx yyy ggg mmm node);
my @a = sort MySort @x;
Alternatively:
sub MySort {
my $P = 'node';
return ($a eq $P ? 0 : 1) <=> ($b eq $P ? 0 : 1)
|| $a cmp $b;
}
Upvotes: 5
Reputation: 239890
If you don't want to write this kind of thing by hand, you can use Sort::ByExample, which is specifically made to sort a list of predefined values to the front of the list, if they appear, and sort the remainder how you like. For your example:
use Sort::ByExample;
my $sorter = Sort::ByExample->sorter(
['node'],
sub { $_[0] cmp $_[1] }
);
my @x = qw (abc def xxx yyy ggg mmm node);
print join "\n", $sorter->(@x);
Or if you really want a sub you can use with the sort
builtin:
use Sort::ByExample;
my $mysort = Sort::ByExample->cmp(
['node'],
sub { $_[0] cmp $_[1] }
);
my @x = qw (abc def xxx yyy ggg mmm node);
print join "\n", sort $mysort @x;
Upvotes: 2