in reply to (Hopefully) simple sorting question

$string = "(x1,x1)(x2,y2)........(xn,yn)"

A real, sortable string together with its expected sorted output form would have been helpful, both to give the monks something to work with and to clarify the problem. (The apparently erroneous ` (x1,x1)` first term also doesn't help.)

... sorted by the x co-ordinate, then by y. ... reorder the string by y co-ordinate first, then by x ...

I'm confused by this as to whether you want to sort "by x then by y", or "by y then by x". I will assume the former.

... sorted by the xco-ordinate...

This suggests to me a **Update:** ascending numeric sort.

Given these assumptions, here's an example of the sort of thing explained in Corion's link.

>perl -wMstrict -le "my $u = '(x1,y9)(x11,y8)(x1,y7)(x11,y6)(x2,y5)(x22,y4)(x2,y3)(x22,y2)'; ;; my $s = join '', map { $_->[0] } sort { $a->[1][0] <=> $b->[1][0] || $a->[1][1] <=> $b->[1][1] } map { [ $_, [ $_ =~ m{\d+}xmsg ]] } split m{ (?<= \)) (?= \() }xms, $u ; ;; print qq{'$s'}; " '(x1,y7)(x1,y9)(x2,y3)(x2,y5)(x11,y6)(x11,y8)(x22,y2)(x22,y4)'

**Note:** The original string *must* be split into an array because sort only works on arrays.

**Update:** Here's a version that will be significantly faster if you're sorting lotsa strings or very long strings. See A Fresh Look at Efficient Perl Sorting for a discussion.

>perl -wMstrict -le "my $u = '(x1,y9)(x11,y8)(x1,y7)(x11,y6)(x2,y5)(x22,y4)(x2,y3)(x22,y2)'; ;; use constant WIDTH => 10; my $s = join '', map { substr $_, WIDTH+WIDTH } sort map { sprintf '%0*4$d%0*4$d%s', m{\d+}xmsg, $_, WIDTH } split m{ (?<= \)) (?= \() }xms, $u ; ;; print qq{'$s'}; " '(x1,y7)(x1,y9)(x2,y3)(x2,y5)(x11,y6)(x11,y8)(x22,y2)(x22,y4)'

Comment onRe: (Hopefully) simple sorting questionSelectorDownloadCode