in reply to Re: Keys and Values from Hash
in thread Keys and Values from Hash

I apologize, I was probably unclear. I will try to explain it better:

My goals is to get the appropriate value for it's appropriate key in Hash. For example.

'CUSTOMER1' = 20; 'CUSTOMER2' = 40; 'CUSTOMER3' = 60;

The above keys and values are in %myHash.

Now I want to extract each of the value and store it in appropriate Variable. For example:

$money_spent_customer1 = 20; $money_spent_customer2 = 40;

The problem is, I only find the solution with knowing what are my $customer and typing an IF statement, to check if the current $customer matcher CUSTOMER1 (for example), etc.

I was hopping if there is a better way to store the values inside variables seperetely for each $customer

The end goal of all this is to draw a chart on my HTML page. To see, how much money did certain customer spend. And I want to be automated as possible - so that I tomorow we'll have new customers, I want PERL to generate my HTML without my manual interfering (apart of running the Script).

Replies are listed 'Best First'.
Re^3: Keys and Values from Hash
by AppleFritter (Vicar) on Jul 18, 2014 at 13:02 UTC

    So, if I understand correctly, for each customer -- that is to say, each key of %myHash -- you want a variable named after that customer?

    You could do that with soft references (note that this will fail to compile under use strict, and generate warnings even without it):

    my %myHash = ( "FredFlintstone" => 1000, "BarneyRubble" => 2000, ); foreach (keys %myHash) { $var = "money_spent_$_"; $$var = $myHash{$_}; } say $money_spent_FredFlintstone; # 1000 say $money_spent_BarneyRubble; # 2000

    But I'd strongly advise against this. This is precisely the sort of thing that hashes are for.

      Yes something similar like you wrote!! Do you suggest any better way to do that?

      My end goal is to create an HTML page, which will display a Column Chart. Each column is each $customer, who has its value drawn.

      In bussiness, we have everyday new customers, and so the myHash will change everyday when I run the Script to get the data (which customers did visit us today). That can be completely direferent than yesterday (the names of $customer).

      I am trying to find a good way to filter through myHash each $customer with it's representing value (money).

      I Should ADD impotant info:

      I noticed I have always written here that there is only one possible value from $customer. THIS IS NOT TRUE! My mistake.

      foreach $customer(keys %myHash){ $money_spent_9am = $myHash{$customer}{money9am}; $money_spent_3pm = $myHash{$customer}{money3pm}; }
      This is how I have it now, Ill run some tests if this is what I want.

        Again, correct me if I'm wrong -- what you'd like to do in the end is output a table roughly like the following:

        Customer | Money spent -----------------+------------- Fred Flintstone | 1000 Barney Rubble | 2000 ... | ...

        I'll assume from this point on that that's the case.

        How to best go about this depends on how %myHash is structured, exactly. If it's a hash of hashes, holding (for each customer) a hash with several pieces of information, including the money they spent, proceed as in Re: Keys and Values from Hash to obtain a hash containing only, for each customer, the amount of money they spent. Your original post suggests that this is the case.

        If it's already a hash of that form, you're done. Your reply at Re^2: Keys and Values from Hash suggests that this is the case instead.

        Either way, once you've got the resulting hash, simply iterate over it and output HTML in some way to create your page:

        foreach my $customer (keys %money_spent) { my $money_sent_by_this_customer = $money_spent{$customer}; # do something with $customer and $money_spent_by_this_customer }

        That said, you may not even need to do any of this; you could equally well just do this, obviating the need for an intermediate hash entirely:

        foreach my $customer (keys %myHash) { my $money_sent_by_this_customer = $myHash{$customer}->{"money"}; # do something with $customer and $money_spent_by_this_customer }

        I hope this helps.

        BTW, I'm getting the feeling that you're not so familiar/at ease with the concept of hashes as such yet. Be sure to read up on them -- see Associative array, Programming Perl p. 76-77 (page numbers for 3rd edition), perldata, perlfaq4: Data: Hashes (Associative Arrays), Not Exactly a Hash Tutorial, Perl Hash Howto, etc.

        EDIT: re: your added important info, if you've only got two data points for each customer, money spent at 9am and money spent at 3pm, I'd recommend simply using two separate hashes, each constructed as above. That, or (again) don't use intermediate hashes at all, and just do this:

        foreach my $customer (keys %myHash) { my $money_sent_by_this_customer_at_9am = $myHash{$customer}->{"mon +ey9am"}; my $money_sent_by_this_customer_at_3pm = $myHash{$customer}->{"mon +ey3pm"}; # do something with $customer, $money_spent_by_this_customer_at_9a +m and $money_spent_by_this_customer_at_3pm }
        My end goal is to create an HTML page, which will display a Column Chart

        In that case, here's a long pass up the field for you ..

        #!perl; use strict; use GD; use GD::Graph::bars; # test data my %spend = (); for ('A'..'Z'){ $spend{'Customer_'.$_} = { money9am => int rand(1000), money3pm => int rand(1000) }; }; # graph my $date = scalar localtime; my $graph = GD::Graph::bars->new(800,400); $graph->set( y_label => 'Spend', title => 'Customer spend for '.$date, bar_spacing => 5, cycle_clrs => 1, x_labels_vertical => 1, ) or die $graph->error; $graph->set_x_axis_font(gdMediumBoldFont); $graph->set_y_axis_font(gdMediumBoldFont); # table and graph data my @x=(); my @y=(); my $table = q!<table cellspacing="0" cellpadding="5" border="1">!; for my $cust (sort keys %spend){ my $spend = $spend{$cust}{'money9am'}+$spend{$cust}{'money3pm'}; push @x,$cust; push @y,$spend; $table .= qq!<tr><td>$cust</td><td align="right">$spend</td></tr>!; } $table .= q!</table>!; # plot my $gd = $graph->plot([\@x,\@y]) or die $graph->error; # save chart as gif (my $filename = $date) =~ s/ /_/g; $filename =~ s/://g; open IMG, '>',$filename.'.gif' or die $!; binmode IMG; print IMG $gd->gif; # create html open HTM, '>report.htm' or die $!; print HTM qq(<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http: +//www.w3.org/TR/html4/strict.dtd"> <head><title>Spend for $date</title></head> <body><h3>Spend for $date</h3> <p><img src="$filename.gif" alt="chart"></p> $table </body></html>);
        For more graph options see GDGraph
        poj