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

I'm trying to find a better way of doing the below and only printing the %hash results only once.

so instead of getting:

Four,4,Miss Four,4,Miss Four,4,Miss Three,3,Miss Three,3,Miss Three,3,Hit Two,2,Miss Two,2,Hit Two,2,Miss One,1,Hit One,1,Miss One,1,Miss

I would like:

One,1,Hit Two,2,Hit Three,3,Hit Four,4,Miss
--------
use strict; use warnings; my %hash = ("One","1","Two","2","Three","3","Four","4"); my @lines = ("One", "Two", "Three"); foreach my $i (keys %hash) { foreach my $n (@lines) { if ($i eq $n) { print "$i,", $hash{"$i"}, ",Hit\n"; } else { print "$i,", $hash{"$i"}, ",Miss\n"; } } }

Replies are listed 'Best First'.
Re: Comparing two sets
by kennethk (Abbot) on May 20, 2010 at 13:53 UTC
    You can do this by following the logic in a FAQ: How do I compute the difference of two arrays? How do I compute the intersection of two arrays?. Essentially, this creates a hash with keys that correspond to the entries of @lines. You can then use that hash to check if the entries existed:

    #!/usr/bin/perl use strict; use warnings; my %hash = ("One","1","Two","2","Three","3","Four","4"); my @lines = ("One", "Two", "Three"); my %count; foreach my $element (@lines) { $count{$element}++; } foreach my $i (sort {$hash{$a} <=> $hash{$b}} keys %hash) { if (exists $count{$i}) { print "$i,$hash{$i},Hit\n"; } else { print "$i,$hash{$i},Miss\n"; } } __END__ One,1,Hit Two,2,Hit Three,3,Hit Four,4,Miss

    Your output lines are also much more complex than they need to be; see Quote and Quote like Operators. As well, you don't need to stringify to use something as a hash key - Perl does that automatically. Compare your output lines to the ones I have above.

      Thanks for the links. There's still a lot I need to learn.
        " ... There's still a lot I need to learn. "

        Don't feel alone; I have been playing with this language for 10+ years and I keep running across something new and wonderful every day.

        When I'm asked to rate my Perl knowledge during an interview, I say that "I am a 7.5 out of 10 -- I know the basics fairly well, and some of the more advanced topics; but I also know that there 30% of Perl that I've never used before. However, I do know where to go to read up on what I need to learn about what I don't know." This sometimes (quite often) segues into a discussion about "how do you know what you don't know" and completely derails the interviewer for half an hour or so.

        ----
        I Go Back to Sleep, Now.

        OGB

Re: Comparing two sets
by JavaFan (Canon) on May 20, 2010 at 13:44 UTC
    Untested:
    my %lines = map {($_, 1)} qw [One Two Three]; my %hash = qw [One 1 Two 2 Three 3 Four 4]; foreach my $key (sort {$hash{$a} <=> $hash{$b}} keys %hash) { print "$key,", $hash{$key}; print $lines{$key} ? ",Hit\n" : ",Miss\n"; }