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

Hi I´m extremely new to Perl and need help with this problem. I have two arrays that consists of usernames. One of the arrays only consists of one username of each and the second one consists of multiples of the same usernames fond i array1. How to compare these two arrays and count how many times each element is found in array two. I allso want to print the results Example output

user1:1 user2:3 user3:9

Replies are listed 'Best First'.
Re: Compare elements from two arrays and count
by toolic (Bishop) on Apr 24, 2015 at 14:48 UTC
Re: Compare elements from two arrays and count
by flexvault (Monsignor) on Apr 24, 2015 at 15:13 UTC

    Welcome skalman,

    Maybe a hash is what you want. Build the hash so that the names from 'array 2' are the keys and the key value is the counter, i.e. (untested):

    my %hash = (); for my $no ( 0..$#array2 ) { if ( $array2[$no] ) { $hash{ $array2[$no] }++; } }
    To print, just do the following:
    foreach my $key ( sort keys %hash ) { print "$key:$hash{$key}\n"; }
    In general, Perl hashs are perfect for this type of requirement.

    UPDATE:Fixed as 'perl' Laurent_R :-)

    Regards...Ed

    "Well done is better than well said." - Benjamin Franklin

      This should be reading array2 (where there are multiple occurrences of the users) rather than array1 for populating the counter hash, shouldn't it?

      Je suis Charlie.

        Laurent_R,

        You are correct, as usual!

        Regards...Ed

        "Well done is better than well said." - Benjamin Franklin

Re: Compare elements from two arrays and count
by davido (Cardinal) on Apr 26, 2015 at 05:21 UTC

    I would probably do it like this:

    use strict; use warnings; my @array1 = qw/ jed jethro zed zug /; my @array2 = qw/ jed jed jed zack zed zug zug /; print join(':', @$_), "\n" for count_occurrences( \@array1, \@array2 ) +; sub count_occurrences { my( $wanted, $have ) = @_; my %counter; @counter{@$wanted} = (0)x@$wanted; $counter{$_}++ for @$have; return map { [ $_ => $counter{$_} ] } @$wanted; }

    The output is:

    jed:3 jethro:0 zed:1 zug:2

    Notice how this method first sets counters to zero for all elements in @array1. Then it adds a count of those names in @array2 that appeared in @array1. Then a data structure is returned, and we print it.

    The nuance here is that if a name appears in @array2 but not in @array1, it won't show up in the final count. After reading your question a couple of times, I got the impression that this behavior would be desirable. Another nuance is that the output will appear in the original order of names from @array1.


    Dave