user6201481
user6201481

Reputation: 39

Why Perl Sort function cannot arrange array's element in my expected incremental manner?

Perl Sort function unable to arrange array elements in my expected incremental manner

@array_sort = sort { $a <=> $b } @array

@array = ("BE_10", "BE_110", "BE_111", "BE_23", "BE_34", "BE_220", "BE_335");
@array_sort = sort { $a <=> $b } @array;
print "array_sort = @array_sort\n";

Expected result: array_sort = BE_10 BE_23 BE_34 BE_110 BE_111 BE_220 BE_335

Actual result: array_sort = BE_10 BE_110 BE_111 BE_23 BE_34 BE_220 BE_335

Upvotes: 0

Views: 86

Answers (2)

ikegami
ikegami

Reputation: 386206

Always use use strict; use warnings;. It would have found your problem, which is that all your strings have the numerical value of zero. Since all strings are numerically identical, the sort function you provided always returns zero. Because of this, and because Perl used a stable sort, the order of the strings remained unchanged.

You wish to perform a "natural sort", and there are modules such as Sort::Key::Natural that will do that.

use Sort::Key::Natural qw( natsort );

my @sorted = natsort @unsorted;

Upvotes: 7

Shawn
Shawn

Reputation: 52449

Sounds like a good case for a Schwartzian transform.

If the prefix is always going to be the same and it's just the numbers after the underscore that differ:

my @array = ("BE_10", "BE_110", "BE_111", "BE_23", "BE_34", "BE_220", "BE_335");

my @array_sort = map { $_->[0] }
                 sort { $a->[1] <=> $b->[1] }
                 map { [ $_, (split /_/, $_)[1] ] } @array;

print "array_sort = @array_sort\n";

And if it might be different:

my @array = ("BE_10", "BE_110", "BE_111", "BE_23", "CE_34", "BE_220", "CE_335");

my @array_sort = map { $_->[0] }
                 sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] }
                 map { [ $_, split(/_/, $_) ] } @array;

print "array_sort = @array_sort\n";

Basic idea is that you decompose the original array into a list of array refs holding the original element and the transformed bit(s) you want to sort on, do the sort, and then extract the original elements in the new sorted order.

Upvotes: 4

Related Questions