Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi how can we sort this:
$arr = [ '1 - foo - xxx', '5 - foo - abc', '4 - foo - efg', '2 - foo - atc', '3 - foo - ggg', '1 - bar - aaa', '2 - bar - ttt', '3 - bar - xxx', '5 - bar - akk', '4 - bar - jjg', '1 - bar - atc', '2 - bar - yyg', '5 - bar - gga', '3 - bar - ttt', '4 - bar - gag' ];
Into this:
$sortedar = [ '1 - foo - xxx', '2 - foo - atc', '3 - foo - ggg', '4 - foo - efg', '5 - foo - abc', '1 - bar - aaa', '2 - bar - ttt', '3 - bar - xxx', '4 - bar - jjg', '5 - bar - akk', '1 - bar - atc', '2 - bar - yyg', '3 - bar - ttt', '4 - bar - gag' '5 - bar - gga', ];
So $arr is sorted on the basis of it's numerical value series (1,2,3,4,..N). In this case N=5, and N can be anything.

Replies are listed 'Best First'.
Re: How to Sort Numerical String
by Joost (Canon) on May 17, 2007 at 11:55 UTC
    Is this homework? See sort

    update: also you're not sorting based on N at all. If you did, your sorted list would start with '1 - foo - xxx', '1 - bar - aaa', '1 - bar - atc' (in whatever order).

    You appear to be splitting the array into parts based on some unknown criteria, then sorting those parts based on N, and then recombining the parts.

Re: How to Sort Numerical String
by derby (Abbot) on May 17, 2007 at 12:24 UTC

    So $arr is sorted on the basis of it's numerical value series (1,2,3,4,..N). In this case N=5, and N can be anything.

    No it's not ... if were sorted based on it's numerical value, it would have all the ones up front. At first I thought maybe it was a fielded sort (with fields being separated by dashes) but even that's not the case. I really don't see a real order here. Maybe some type of funky quasi in-situ sort where all the foos are sorted and then all the bars (where the foo and bar relationship is not sorted but keeps the order of the original array).

    If that's the case, a simple sort {code foo} @array is not going to do the trick -- you're going to need to break the array into parts based on the second field, sort those arrays and then stitch them back together based on the original order of the second field.

    -derby
Re: How to Sort Numerical String
by scorpio17 (Canon) on May 17, 2007 at 13:23 UTC
    Here's one way: step through the array N elements at a time, sorting each subset as you go using the "Schwartzian Transform".

    use strict; my $N = 5; my $arr = [ '1 - foo - xxx', '5 - foo - abc', '4 - foo - efg', '2 - foo - atc', '3 - foo - ggg', '1 - bar - aaa', '2 - bar - ttt', '3 - bar - xxx', '5 - bar - akk', '4 - bar - jjg', '1 - bar - atc', '2 - bar - yyg', '5 - bar - gga', '3 - bar - ttt', '4 - bar - gag' ]; my $nelem = @$arr; if ($nelem%$N) { die "error - array length not even multiple of $N.\n"; } for my $i (0 .. $nelem/$N-1) { my @temp = @$arr[$N*$i..$N*($i+1)-1]; @temp = map { $_->[1] } sort { $a->[0] <=> $b->[0]} map { [ (my $x) = split(/\s+/, $_) , $_] } @temp; for my $t (@temp) { print "$t\n"; } }