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

Dominus vobiscum, fratres!

I've been trying to create I short routine based on hash arrays that should supposedly add letters to an ordinary array. It first checks if a letter has already been added to that array to avoid duplication.

I've tried all my tricks but the bloody (erm, excuse my French, brothers) thing keeps refusing to work. Can you have a look at the code and tell me what I'm missing.

May the Lord of Perl bless you abundantly!

Kyrie eleison!

PS: Here's the snippet...
The hash array that seems to be causing the trouble is %digit.
The comparisons that refuse to work are the first ones in the if-comparisons below.

for ($i=3; $i<=5; $i++) { $nv = join '',$big[$i],'v'; $nl = join '','l',$big[$i],'1'; $nm = join '','m',$big[$i],'1'; $nu = join '','u',$big[$i],'1'; if ($operation{$nv} eq 'plus') { $x = $digit{$nl}; if (@$x !~ /$digit{$nu}/ && $x ne $digit{$nu}) {push (@$x, $di +git{$nu});} if (@$x !~ /$digit{$nm}/ && $x ne $digit{$nm}) {push (@$x, $di +git{$nm});} } else { $x = $digit{$nu}; if (@$x !~ /$digit{$nl}/ && $x ne $digit{$nl}) {push (@$x, $di +git{$nl});} if (@$x !~ /$digit{$nm}/ && $x ne $digit{$nm}) {push (@$x, $di +git{$nm});} } }

Replies are listed 'Best First'.
Re: Comparison problem
by edan (Curate) on Oct 27, 2004 at 15:57 UTC

    Perhaps you mean to say something like:

    push @$x, $digit{$nu} unless grep { $_ eq $digit{$nu} } @$x;
    --
    edan

      That worked, too!

      Hmmm... I'd better do some more reading on "grep" and "map".

Re: Comparison problem
by borisz (Canon) on Oct 27, 2004 at 15:51 UTC
    Without looking into your problem, the @$x !~ /$digit{$xx}/ looks wrong. Since you compare the number of items in the array $x reference to with the string digit{$xx}. I think you want "@$x" !~ /$digit{$xx}/.
    Update: revdiablo noticed that I wrote != but I mean !~. Fixed now.
    Boris
      That solved it!

      Thank you, brother!

Re: Comparison problem
by Roy Johnson (Monsignor) on Oct 27, 2004 at 16:49 UTC
    It's not clear to me what you're doing with $x -- are you using it as a symbolic ref? -- but the common way to construct a unique set is to use a hash. If $x were a hashref instead of an arrayref, you could simply use keys %$x to get the list -- though it would not be in original insertion order.

    If you need the arrayref (or the ordering) you could keep a separate hash to track which values have already been inserted. That would look something like:

    push @$x, $digit{$nu} unless $seen{$digit{$nu}};
    Or you could use Tie::Hash::Sorted to get the same effect from a hash.

    Caution: Contents may have been coded under pressure.
      Indeed, insertion order is important in my code but $x is simply used as an abbreviation for $digit{$nu}, $digit{$nl} and the other hashes I've included in my code. It facilitates cut'n'paste... ;-)

      Thanks for the code snippet, though. I'll work on it...

Re: Comparison problem
by Taulmarill (Deacon) on Oct 27, 2004 at 16:39 UTC
    as a suggestion:
    you can write for ($i=3; $i<=5; $i++) {} also as for my $i ( 3..5 ) {}
      I haven't tried "my" or "strict" yet. I plan to take that step as soon as I feel confident with a larger set of perl commands. Thanks for pointing me to that direction, though!
        Unfortunately, that's not quite the right attitude. That's like saying "I'll learn how the safety switch works after I've mastered pulling the trigger." Kind of.

        Turning on 'strict' (one of the consequences of which is that you'll have to 'my' your variables) helps you catch noob errors. When you've mastered that fundamental mode of programming, then you'll be better equipped to foray into the minefields of global variables, symbolic references, dynamic subroutines, etc.