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

Hi all,

Can I get better solution to compare two arrays and get the count?
Here is my code.
@selected_data = qw(13 76 90 13 77 100 76 300 13 65 400 74 89 34 65); @all_data = qw(1 5 2 8 12 87 13 76 98 77 89 90 11 65 43 74 43 32 34 67 +); $total = 0; foreach $sub_select (@selected_data) { foreach $sub_all (@all_data) { if($sub_select eq $sub_all) { $total++; } } } print "Count -> $total\n";
Thanks

Replies are listed 'Best First'.
Re: Can I get better approach to get solution
by kyle (Abbot) on Feb 13, 2007 at 04:31 UTC

    The solution posted by dragonchild is close. It just doesn't account for the fact that @selected_data has duplicate items in it.

    @selected_data = qw(13 76 90 13 77 100 76 300 13 65 400 74 89 34 65); @all_data = qw(1 5 2 8 12 87 13 76 98 77 89 90 11 65 43 74 43 32 34 67 +); my %all_hash; $all_hash{$_} = undef for @all_data; my $total = scalar grep( exists $all_hash{ $_ }, @selected_data ); print "Count (kyle) -> $total\n";
Re: Can I get better approach to get solution
by BrowserUk (Patriarch) on Feb 13, 2007 at 04:34 UTC

    Your rules for what you count are a little strange, but this produces the same result.

    Update 1: No it doesn't! You caught me out with the duplication of value 43 in @all_data.

    Is it any better?

    C:\test>p1 use List::Util qw[ sum ];; @selected_data = qw(13 76 90 13 77 100 76 300 13 65 400 74 89 34 65); @all_data = qw(1 5 2 8 12 87 13 76 98 77 89 90 11 65 43 74 43 32 34 67 +);; ++$seen{ $_ } for @selected_data, @all_data;; print sum map{ $_ > 1 ? $_ - 1 : () } values %seen;; 13

    Update2: This is better.

    @selected_data = qw(13 76 90 13 77 100 76 300 13 65 400 74 89 34 65); @all_data = qw(1 5 2 8 12 87 13 76 98 77 89 90 11 65 43 74 43 32 34 67 +); @seen{ @all_data } = ();; exists $seen{ $_ } and $count++ for @selected_data;; print $count;; 12

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      This doesn't work because the number 43 appears twice in @all_data but not at all in @selected_data. Your algorithm counts it as a match when it shouldn't be.

      Thanks for your help.
Re: Can I get better approach to get solution
by dragonchild (Archbishop) on Feb 13, 2007 at 03:54 UTC
    You're looking for the number of elements in the intersection between the two arrays. You're looking for this:
    my %x; $x{$_} = undef for @selected_data; my %y; $y{$_} = undef for @all_data; my $total; foreach my $k ( keys %x ) { $total++ if exists $y{$k}; } print "Count -> $total\n";

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      dragonchild,
      that doesn't work.
      The count return from the code is "8", which is not correct, but correct result is "12".

      I would like to compare the elements in @selected_data with @all_data array, if elements from @selected_data array found in @all_data, then increment the count.
      thanks