Wednesday 24 March 2010

PERL: comparing if a set of variables have the same value

This post originates because I was reading a post from PerlMongers back in 2001

I posted here because the perlish way of using double negation logic in '!grep != ' or the trick to encode the variables to a string and check what it remains after removing a string. Sometimes this tricks would be useful (despite not pretty).

In response to draegtun comment:

Thanks for the Perl6::Junction hint. But probably I will go for List::MoreUtils
DB<8> use List::MoreUtils qw(any all)

DB<2> $a=1; $b=1;$c=1;$d=1;$e=1;$z=2

DB<9> (all{$_ ==$a} ($a,$b,$c,$d,$e, $z))? print "doing st because equal\n" : print "sorry not equal\n"
sorry not equal

DB<10> (all{$_ ==$a} ($a,$b,$c,$d,$e))? print "doing st because equal\n" : print "sorry not equal\n"
doing st because equal




 in reply to Re:
Re: Re: Fastest way to compare multiple variables?

in thread Fastest
way to compare multiple variables?

on May 15, 2001 at 21:10 UTC ( #80620=perlquestion: print w/ replies,
xml )

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

Hi, Is there anyway (without using hashes) to do
something like
if ($a == $b == $c == $d) {
&do_something
}
What I have: 15-20 variables ALREADY have their values (integers)
What I need: tell if all those variables have a same value or not
What I know: there are already ways to do that by using arrays/hashes.
Or, hash is still the fastest way? Thank you...
TIMTIWODI 1:
Re:
Fastest way to compare multiple variables?

by Masem (Monsignor) on May 15, 2001 at
21:14 UTC

    TIMTOWODI:
    if ( !grep { $_ != $a } ($b, $c, $d, $e...) ) { &do_something }

    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
TIMTIWODI 2: Merlin way:
on May 15, 2001 at 21:51 UTC ( #80645=note: print w/ replies,
xml )
use CGI;
@array1 = param('datalist1');
@array2 = param('datalist2');
@array3 = param('datalist3');
If you could make that instead:
my %data = map { $_ => [param $_] }
qw(datalist1 datalist2 datalist3);
Then we can compare their lengths
with:
sub compare {
my @lengths = map { scalar @{$data{$_}} } qw(datalist1 datalist2 dat
+alist3);
my $first = shift @lengths;
$first == $_ or return 0 for @lengths;
return 1;
}
See how much easier? Regularity in
variable names is almost always a sign that they should be part
of a larger structure instead. -- Randal L. Schwartz, Perl
hacker
TIMTIWODI 3: using s///g . Probably it is slower if you have a
lot of values but the idea of eliminating things and count how many
remain doing it in a string instead with a grep is 'another way of
doing it'
Try this:
#!/usr/local/bin/perl -w
use strict;
my @list=("abcd123","abcd143","abcd123","abcd123");
$_=join("",@list);
s/$list[0]//g;
print "not equal\n" if ($_);


1 comment:

draegtun said...

TIMTIWODI 4:


use Perl6::Junction 'any';

if ($a == any($b, $c, $d, $e)) {
do_something();
}

Can't comment on speed but certainly most aesthetically pleasing version methinks.

/I3az/