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

Hello Monks,
I have a hash of hashes in the following format.
%HoH = ( '192.168.0.1' => { user => "fred", pass => "barney", }, '192.168.0.2' => { user => "george", pass => "tester", }, '192.168.0.3' => { user => "homer", pass => "abc123", }, '192.168.0.6' => { user => "fred", pass => "barney", }, );


Now i need to count the unique users ('user') from this Hash of hashes. Would anyone suggest me a best way for performing this operation.
For the above example the count should 3 since the user 'fred' exists twice.
Thanks !

Replies are listed 'Best First'.
Re: Retrieve unique values from Hash of Hashes
by ikegami (Patriarch) on Nov 09, 2009 at 21:10 UTC
    my %seen; my $num_unique_users = grep !$seen{ $HoH{$_}{user} }++, keys(%HOH);

    If you actually want the name of the users:

    my %seen; my @unique_users = grep !$seen{ $HoH{$_}{user} }++, keys(%HOH);
    my %seen; my @unique_users = grep !$seen{$_}++, map $HoH{$_}{user}, keys(%HOH);

      Oh, man. That's tight.

      Here's a beginner's version:

      use strict; use warnings; use 5.010; my %HoH = ( '192.168.0.1' => { user => "fred", pass => "barney", }, '192.168.0.2' => { user => "george", pass => "tester", }, '192.168.0.3' => { user => "homer", pass => "abc123", }, '192.168.0.6' => { user => "fred", pass => "barney", }, ); my %unique; foreach my $key (keys %HoH) { my $user = $HoH{$key}->{'user'}; $unique{$user} = 1; } my $count = keys %unique; say $count; --output:-- 3
Re: Retrieve unique values from Hash of Hashes
by biohisham (Priest) on Nov 10, 2009 at 00:39 UTC
    To add to ikegami's solution, this is how you would print the unique names:
    print "$HoH{$_}{user}\n" for (@unique_users);

    updated....


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.

      There's a bug in my code. You seem to imply the bug is simply my choice of array name. I disagree. If that's the bug, we have redundant code ($HoH{$_}{user}). And simply put, it makes no sense to end up with a bunch of IP addresses when looking for unique users.

      My code should have been

      my %seen; my @unique_users = grep !$seen{$_}++, map $HoH{$_}{user}, keys(%HOH);