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

Hi Monks!

I am trying to count how many "houses" each person has once I get the data from the database, I included a data sample so you can see better what I am trying to do.
I tried the way I have in this sample code here but it isn’t working.
Any suggestions on how I could do this?
Sample code:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; ... my @all_profile; my %homes_by_names; foreach my $row ( @{ $sql } ) { my %profile; $profile{ NAME } = $row->{'name'}; $profile{ ADDRESS } = $row->{'address'}; $profile{ HOME } = $row->{'home'}; # I will need to count the how many homes here push ( @{ $homes_by_names{$profile{ HOME } } }, \%profile); push @all_profile, { 'HOME COUNT' => scalar @{ $homes_by_names{HO +ME} }; push @all_profile, \%profile; } print Dumper \@all_profile; $VAR1 = [ { 'NAME' => 'John Doe', 'ADDRESS' => 'Main Street', 'HOME' => 'House 1', 'HOME COUNT' => '3', }, ... =data # Sample data to show how I need to count how many Houses per person John Doe, Main Street, House 1 John Doe, Main Street, House 1 John Doe, Main Street, House 1 Mary Lou, Central Street, House 1 Mary Lou, Central Street, House 1 Mary Lou, Central Street, House 1 Mary Lou, Central Street, House 1 Jane B,. Squere Rd., House 1 Maria D., Pat street, House B Maria D., Pat street, House B

Thanks for looking!!!

Replies are listed 'Best First'.
Re: Adding an element to an array
by AppleFritter (Vicar) on Oct 14, 2015 at 18:51 UTC

    If you're pulling data from an SQL database, the best approach may be to let the database do the work for you; SQL has a COUNT aggregate function. Something along the following lines, perhaps:

    SELECT Name, COUNT(Home) AS HomeCount FROM People GROUP BY Name;
    
      Unfortunately I cant use the database for this one, since it is already too complex, I need to try using Perl.

        There are plenty of ways to unobtrusively change the statement already being used. Can you show us the SQL statement used to pull the data?

Re: Adding an element to an array
by poj (Abbot) on Oct 14, 2015 at 19:30 UTC
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @all_profile; my %homes_by_names; while (<DATA>){ chomp; my @f = split ',',$_; my %profile; $profile{ NAME } = $f[0];#$row->{'name'}; $profile{ ADDRESS } = $f[1];#$row->{'address'}; $profile{ HOME } = $f[2];#$row->{'home'}; # I will need to count the how many homes here ++$homes_by_names{ $profile{ NAME } }; push @all_profile, \%profile; } for (@all_profile){ $_->{'HOME COUNT'} = $homes_by_names{ $_->{ NAME } }; } print Dumper \@all_profile; __DATA__ John Doe, Main Street, House 1 John Doe, Main Street, House 1 John Doe, Main Street, House 1 Mary Lou, Central Street, House 1 Mary Lou, Central Street, House 1 Mary Lou, Central Street, House 1 Mary Lou, Central Street, House 1 Jane B,. Squere Rd., House 1 Maria D., Pat street, House B Maria D., Pat street, House B
    poj
      Hi!
      I am trying to use your code but I am getting this error:
      Error: Global symbol "%row" requires explicit package name at... My data structure is like this:
      [ [ "John Doe", "Main Street", "House 1", ], [ "John Doe", "Main Street", "House 1", ], ... ]

      Trying to apply your code in here:
      my %homes_by_names; foreach my $row ( @data ) { $row{'HOME_COUNT'} = $homes_by_name{ $row{ HOME } }; }

      Thanks for looking!
        $row is a hashref. Try:
        $row->{'HOME_COUNT'} = $homes_by_name{ $row->{ HOME } };

                Software efficiency halves every 18 months, thus compensating for Moore's Law.

      Its getting there, I am getting an error as:
      Can't use string ("3") as an ARRAY ref while "strict refs"
      Any idea why?

        Witness the following:

        $ perl -Mstrict -Mdiagnostics -E 'my $a = "3"; say $a->[0];' Can't use string ("3") as an ARRAY ref while "strict refs" in use at - +e line 1 (#1) (F) You've told Perl to dereference a string, something which use strict blocks to prevent it happening accidentally. See "Symbolic references" in perlref. This can be triggered by an @ o +r $ in a double-quoted string immediately before interpolating a varia +ble, for example in "user @$twitter_id", which says to treat the conten +ts of $twitter_id as an array reference; use a \ to have a literal @ symbol followed by the contents of $twitter_id: "user \@$twitter_i +d". Uncaught exception from user code: Can't use string ("3") as an ARRAY ref while "strict refs" in use +at -e line 1.

        If you are getting this message, then your code is doing what my code demonstrates. It may take a more complex path to get there, but the result it the same; some variable that you think has an array reference in it actually has the string "3", and you are attempting to dereference it.


        Dave

        You will need to show the code that gives that error

        poj