in reply to Help needed to make a conditional statement

First, look at what you're doing here:

my %lookup; @lookup{@in} = (); # For every $elem in @db ... foreach my $elem (@db) { # see if it exists in the lookup hash ... if (exists $lookup{$elem}) { # and if it does then search @db (*again*) looking for # items that do not appear in the lookup hash. You're # also modifying the array you're iterating over (@db), # which can yield unpredictable results, so don't do it ;) @db = grep {not exists $lookup{$_}} @db; } }

In the second case, you could utilize a grep very similar to the one above, and simplify the if/push syntax.

How about this as a solution:

my (%db_lookup, %in_lookup); @db_lookup{@db} = (); @in_lookup{@in} = (); if ($condition1) { # Dunno what your test conditions are, so... @db = grep { not exists $in_lookup{$_} } @db; } elsif ($condition2) { push @db, grep { not exists $db_lookup{$_} } @in; }

Hope that helps.

Replies are listed 'Best First'.
Re: Re: Help needed to make a conditional statement
by jonnyfolk (Vicar) on Dec 04, 2002 at 16:42 UTC
    After much fiddling around I have arrived at the following:
    #!/usr/bin/perl -w #use strict; use CGI ':standard'; my @db = (1, 3, 5, 7, 9, 11); my @in = (1, 2, 5, 8, 9, 10, 13); my $var = 7; # I have this variable available to indicate the length o +f the array my (%db_lookup, %in_lookup); @db_lookup{@db} = (); @in_lookup{@in} = (); $count = 0; while ($count < $var) { if (exists $in_lookup{$count}, @db) { @db = grep { not exists $in_lookup{$_} } @db; $count += 1; } elsif (not exists $in_lookup{$count}, @db) { push @db, grep { not exists $db_lookup{$_} } @in; $count += 1; } } print "view: @db";
    That does what I need when strings match. However when strings don't match the db is unchanged from the original, wheras I need the contents of @in pushed into @db:
    my @db = (1, 3, 5, 7, 9, 11); my @in = (21, 22, 25, 28, 29, 210, 213);
    Where am I going wrong?

      A couple of problems here. First, $count will need to be specified in a more maintainable manner, such as using scalar on your arrays and finding the greater value. Second, you're looking at the value of $count in your evaluations, not the value of the index in your arrays that $count points to. Finally, by adding @db to your conditionals i.e.,if (exists $in_lookup{$count}, @db) you are ensuring that the test will return 'true' always unless the array is empty. So, the way you've got it now it executes the first conditional branch 7 times and then exits.

      I'm still struggling to see what exactly you're attempting -- if element A in array @in exists in array @db, remove A from @db. Else, if element A does not exist in array @db, append it to @db. Is this right?

        Sorry - I see I wasn't very clear, although you're absolutely right in your interpretation. After operating on the first input @in the @db should contain
        my @db = (1, 3, 5, 7, 9, 11); my @in = (1, 2, 5, 8, 9, 10, 13); # results in: my @db = (3, 7, 11);
        operating on the second example should give:
        my @db = (1, 3, 5, 7, 9, 11); my @in = (21, 22, 25, 28, 29, 210, 213); # results in: my @db = (1, 3, 5, 7, 9, 11, 21, 22, 25, 28, 29, 210, 21 +3);
      This is actually a reply to fever.

      The reference to $count is actually pure guesswork on my part. The problem is that I cannot find a way to say "if the input exists - take it out, if it doesn't - put it in". Obviously inclusion of the $count mechanism is more problematical than I'd anticipated but I can't find another approach which comes close to letting me say, "while values of @in match values of @db or the converse".

      That, I think is the crux of the problem!