Hi shamat,
Wow, this question brings me back to what was - as far as I can remember - probably the first time I visited PerlMonks :-) Specifically, it was Re: How do I do a natural sort on an array?, that snippet was very helpful to me over the years. So I revived it and applied it to your code:
use warnings; use strict; my @matrix = ( ["A12a1", "img5", "x456", "y456"], ["A1a2", "img2", "x123", "y456"], ["A1a1", "img1", "x123", "y123"], ["A10a1", "img4", "x456", "y123"], ["A1a12", "img3", "x456", "y789"], ); my @sorted = sort natsort @matrix; use Data::Dump 'pp'; print pp \@sorted; sub natsort { # sort by first column (note the dereferencing) my @a = split /(\d+)/, $a->[0]; my @b = split /(\d+)/, $b->[0]; my ($A,$B); while (defined($A = shift @a) and defined($B = shift @b)) { my $res = ($A =~ /\d/) ? $A <=> $B : $A cmp $B; return $res if $res; } return defined $A ? -1 : 1; } __END__ [ ["A1a1", "img1", "x123", "y123"], ["A1a2", "img2", "x123", "y456"], ["A1a12", "img3", "x456", "y789"], ["A10a1", "img4", "x456", "y123"], ["A12a1", "img5", "x456", "y456"], ]
The way this works is by breaking each string up into its digits and non-digits, for example "A12a1" becomes ("A", 12, "a", 1), and then each element is compared individually. This does assume that the two strings being compared follow the same digit/non-digit pattern. Also, it's not a particularly efficient sort method, as it does a lot of work for each comparison. But it was just a walk down memory lane anyway :-)
Of course, there are also modules to do the hard work, just one example is Sort::Key::Natural.
By the way, I think you've got a mistake in your test data, you overwrite $matrix[1], that's why I've initialized the data as I showed.
Hope this helps,
-- Hauke D
In reply to Re: natural sort on array of arrays
by haukex
in thread natural sort on array of arrays
by shamat
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |