M
Marc Girod
Hi,
I often have to sort strings with embedded numbers, which gets into the problem that neither cmp nor <=> is appropriate to deal with them.
Making ad-hoc sort functions is nearly trivial, but cumbersome e.g. for one-liners.
I tried thus to write a sort function which would parse out the string parts from the numeric ones.
Here is what I came up with.
-8<---------------
package UCmp;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(ucmp);
sub ucmp {
my $a = eval '$' . caller . '::a';
my $b = eval '$' . caller . '::b';
my @t = $a =~ /(\D*)(\d*)/g; pop @t; pop @t;
my @s = $b =~ /(\D*)(\d*)/g; pop @s; pop @s;
my $l = ((@t <= @s)? @t : @s) / 2;
my $ret;
while ($l--) {
$ret = ((shift @t) cmp (shift @s) or (shift @t or 0) <=> (shift @s or 0));
$l = 0 if $ret;
}
return ($ret or @t <=> @s);
}
1;
-8<-----------------
And a test example:
$ cat bar
#!/usr/bin/perl -w
use feature qw(say);
use UCmp;
say for sort ucmp qw(
a12b34
a2c
b23
a7
a7b
23
);
$ ./bar
23
a2c
a7
a7b
a12b34
b23
Would you care to criticize it?
Thanks,
Marc
I often have to sort strings with embedded numbers, which gets into the problem that neither cmp nor <=> is appropriate to deal with them.
Making ad-hoc sort functions is nearly trivial, but cumbersome e.g. for one-liners.
I tried thus to write a sort function which would parse out the string parts from the numeric ones.
Here is what I came up with.
-8<---------------
package UCmp;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(ucmp);
sub ucmp {
my $a = eval '$' . caller . '::a';
my $b = eval '$' . caller . '::b';
my @t = $a =~ /(\D*)(\d*)/g; pop @t; pop @t;
my @s = $b =~ /(\D*)(\d*)/g; pop @s; pop @s;
my $l = ((@t <= @s)? @t : @s) / 2;
my $ret;
while ($l--) {
$ret = ((shift @t) cmp (shift @s) or (shift @t or 0) <=> (shift @s or 0));
$l = 0 if $ret;
}
return ($ret or @t <=> @s);
}
1;
-8<-----------------
And a test example:
$ cat bar
#!/usr/bin/perl -w
use feature qw(say);
use UCmp;
say for sort ucmp qw(
a12b34
a2c
b23
a7
a7b
23
);
$ ./bar
23
a2c
a7
a7b
a12b34
b23
Would you care to criticize it?
Thanks,
Marc