in reply to ugly nested if's

You're looking for one of two things. You can either create a hash with the keys being the second list or you can use grep.
my @list1 = get_from_some_place(); my @list2 = get_from_some_other_place(); -------- # Hash method my %lookup_hash; @lookup_hash{@list2} = undef; # This is a hashslice. We don't care abo +ut the values. unless (exists $lookup_hash{$list1[0]}) { # Do something here } -------- # grep method unless (grep { $_ eq $list1[0] } @list2) { # Do something here }

In general, the hash is faster, but takes more memory.

------
We are the carpenters and bricklayers of the Information Age.

Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Replies are listed 'Best First'.
Re: ugly nested if's
by Abigail-II (Bishop) on Apr 22, 2004 at 15:25 UTC
    Both methods only check whether the first entry of the first list occurs in the second list. I highly doubt that your hash method is faster in such a case.

    However, it was my understanding the OP wanted to know whether the first list contains entries that aren't in the second list. This is a FAQ, and a hash solution ought to be used, as that gives you linear behaviour (assuming all your hash inserts go in constant time on average). A grep method will be quadratic, and for any list that doesn't have a trivial size, it should not be taking into consideration. After all, both methods use a linear amount of memory.

    Abigail

Re(2): ugly nested if's (broken idiom)
by bart (Canon) on Apr 23, 2004 at 09:08 UTC
    Just a nitpick: I do not like your statement with the assignment to the hash slice.
    @lookup_hash{@list2} = undef;
    It'll do exactly what you want, but only in this particular case. It exhibits a lack of elegance: it looks like it's doing something other than what it's really doing. Let me demonstrate what I mean, by assigning a different value:
    my @list2 = qw(one two three); my %lookup_hash; @lookup_hash{@list2} = 'foo'; use Data::Dumper; print Dumper \%lookup_hash;
    Result:
    $VAR1 = { 'three' => undef, 'one' => 'foo', 'two' => undef };
    If you were expecting to see "foo" for every value, think again. You are assigning an explicit value (in your code, undef) to the first hash element in the slice, and an implicit undef to all the others.

    As for better idioms (IMO)... In this particular case, I'd assign an implied undef for all hash elements, no exceptions:

    @lookup_hash{@list2} = ();
    In order to assign the same explicit value to all:
    @lookup_hash{@list2} = ('foo') x @list2;

    --
    Thank you. I'll get off my soap box now.

      Actually, the idiom I wanted to use was
      undef @lookup_hash{@list};

      But, I've found that it fails for symbolic references living in packages other than the one you're executing in under some builds of Perl. Doing an explicit assignment (either with undef or the empty list) works in all builds I've tried.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose