Strip equal portion of strings / version comparison
Strip equal portion of strings / version comparison
am 01.01.2008 19:02:47 von s1037989
Starting with:
$a = '1.1.2';
$b = '1.1.10';
Is there an elegant, one-liner way -- possibly using RE -- to yield:
$a = '2';
$b = '10';
In other words, strip out the beginning equal portion of 2 strings?
Moreover, how could you compare the original $a and $b such that $b >
$a (as in version comparisons)?
Thanks!
Stefan
Re: Strip equal portion of strings / version comparison
am 01.01.2008 20:17:43 von gbacon
In article ,
Stefan wrote:
: Starting with:
:
: $a = '1.1.2';
: $b = '1.1.10';
:
: Is there an elegant, one-liner way -- possibly using RE -- to yield:
:
: $a = '2';
: $b = '10';
:
: In other words, strip out the beginning equal portion of 2 strings?
:
: Moreover, how could you compare the original $a and $b such that $b >
: $a (as in version comparisons)?
Consider the following code:
$ cat try
#! /usr/bin/perl
use warnings;
use strict;
sub strip_equal {
my($a,$b) = @_;
return if $a eq $b;
local $_ = "$a;$b";
return ($2,$3) if /^(.+\.)(.+);\1(.+)$/;
}
sub cmpv {
my @a = split /\./, $a;
my @b = split /\./, $b;
while (@a && @b) {
my $a = shift @a;
my $b = shift @b;
$a <=> $b && return $a <=> $b;
}
@a <=> @b;
}
my @cases = (
["1.1.10", "1.1.2"],
["1.1.2", "1.1.2"],
["1.2.3", "4.5.6"],
);
$" = "][";
foreach my $case (@cases) {
our($a,$b) = @$case;
my @eq = strip_equal $a, $b;
my $cmpv = cmpv $a, $b;
print "a=$a, b=$b:\n",
" - strip_equal: [@eq]\n",
" - cmpv: $cmpv\n";
}
$ ./try
a=1.1.10, b=1.1.2:
- strip_equal: [10][2]
- cmpv: 1
a=1.1.2, b=1.1.2:
- strip_equal: []
- cmpv: 0
a=1.2.3, b=4.5.6:
- strip_equal: []
- cmpv: -1
Hope this helps,
Greg
--
For diagrams comprehensiveness is the enemy of comprehensibility.
-- Martin Fowler, "Is Design Dead?"
Re: Strip equal portion of strings / version comparison
am 01.01.2008 20:28:14 von s1037989
On Jan 1, 1:17=A0pm, gba...@hiwaay.net (Greg Bacon) wrote:
> In article
com>,
> =A0 =A0 Stefan =A0 wrote:
>
: snip :
> =A0 =A0 sub strip_equal {
> =A0 =A0 =A0 my($a,$b) =3D @_;
>
> =A0 =A0 =A0 return if $a eq $b;
>
> =A0 =A0 =A0 local $_ =3D "$a;$b";
> =A0 =A0 =A0 return ($2,$3) if /^(.+\.)(.+);\1(.+)$/;
> =A0 =A0 }
> =A0 =A0 sub cmpv {
> =A0 =A0 =A0 my @a =3D split /\./, $a;
> =A0 =A0 =A0 my @b =3D split /\./, $b;
>
> =A0 =A0 =A0 while (@a && @b) {
> =A0 =A0 =A0 =A0 my $a =3D shift @a;
> =A0 =A0 =A0 =A0 my $b =3D shift @b;
>
> =A0 =A0 =A0 =A0 $a <=3D> $b && return $a <=3D> $b;
> =A0 =A0 =A0 }
>
> =A0 =A0 =A0 @a <=3D> @b;
> =A0 =A0 }
: snip :
Those are some great functions!! Thanks!!
>
> Hope this helps,
> Greg
> --
> For diagrams comprehensiveness is the enemy of comprehensibility.
> =A0 =A0 -- Martin Fowler, "Is Design Dead?"
Re: Strip equal portion of strings / version comparison
am 01.01.2008 21:15:10 von gbacon
In article ,
Stefan wrote:
: Those are some great functions!! Thanks!!
I'm glad you liked them. Happy new year!
Greg
--
He who proclaims the godliness of the State and the infallibility of
its priests, the bureaucrats, is considered as an impartial student of
the social sciences. All those raising objections are branded as biased
and narrow-minded. -- Ludwig von Mises, Planned Chaos
Re: Strip equal portion of strings / version comparison
am 02.01.2008 06:07:45 von Charles DeRykus
On Jan 1, 10:02 am, Stefan wrote:
> Starting with:
>
> $a = '1.1.2';
> $b = '1.1.10';
>
> Is there an elegant, one-liner way -- possibly using RE -- to yield:
>
> $a = '2';
> $b = '10';
>
> In other words, strip out the beginning equal portion of 2 strings?
>
> Moreover, how could you compare the original $a and $b such that $b >
> $a (as in version comparisons)?
>
Yet another way:
#! perl -l
use strict; use warnings;
use List::Util qw/max/;
my @s1 = split /\./, $a;
my $strip1 = $s1[-1];
my @s2 = split /\./, $b;
my $strip2 = $s2[-1];
CMP: {
for ( 0 .. max( $#s1, $#s2 ) ) {
my $res = ($s1[$_] || 0) <=> ($s2[$_] || 0);
$res == -1 and print "a is less than b"
and last CMP;
$res == 1 and print "a is greater than b"
and last CMP;
}
print "a is equal to b";
}
__END__
--
Charles DeRykus