Operating System - Linux
1753781 Members
7973 Online
108799 Solutions
New Discussion юеВ

How to access hash values in "arrays of hases" ?

 
SOLVED
Go to solution
Pankaj Yadav_1
Frequent Advisor

How to access hash values in "arrays of hases" ?

My code is as following. Just tell me will it work ?

while(my $data = $sth->fetchrow_hashref) {
my %loopdata;
($Hrs,$Mins,$Secs) = &diffDateTime($data->{'date'},$data->{'time_in'},$times_data->{'time_out'},$times_data->{'date_out'});
$loopdata{'type'}=$data->{'type'};
$loopdata{'interval'}= $Hrs:$Mins:$Secs;
push(@intlist, \%loopdata);
}
my %hash;
my $i=0;
$hash{'total_lhrs'}='00:00:00';
foreach my $interval (@intlist) {
if($interval->[++$i]) {
my $t = $interval->[$i];
my $t2 = $interval->[++$i];
my ($hr, $min, $sec) = split /:/, $t;
my ($hr2, $min2, $sec2) = split /:/, $t2;
my ($hr1, $min1, $sec1) = split /:/, $hash{'total_lhrs'};
my $hr3 = $hr + $hr2 + $hr1;
my $min3 = $min + $min2 + $min1;
my $sec3 = $sec + $sec2 + $sec1;
my $elapsed = ($hr3 * 3600) + ($min3 * 60) + $sec3;
my $hr4 = int $elapsed / 3600;
my $new = $elapsed % 3600 ;
my $min4 = int $new / 60;
my $sec4 = $new % 60 ;
$hash{'total_lhrs'}= sprintf ("%02d:%02d:%02d\n",$hr4,$min4,$sec4);
$i++;
}
}
14 REPLIES 14
James R. Ferguson
Acclaimed Contributor

Re: How to access hash values in "arrays of hases" ?

Hi:

No, in fact it doesn't even compile.

You should always use the 'strict' and 'warnings' pragma. They will save you hours of grief and suffering!

#!/usr/bin/perl
use strict;
use warnings;

Regards!

...JRF...
Pankaj Yadav_1
Frequent Advisor

Re: How to access hash values in "arrays of hases" ?

I have used a hash %loopdata. After that I have pushed the hash in an array.

Can anyone tell me how can I access the values by interval->[][] or in other words the values of the hash when I am inside "foreach" loop?
Marvin Strong
Honored Contributor

Re: How to access hash values in "arrays of hases" ?


The basic syntax is:

print $array[element]->{key}

There is probably a better way to do it, but this is one way.

example:

#!/usr/bin/perl

%flintstones = (
dad => fred,
mom => wilma,
daughter=> pebbles,
dog => dino,
);

push @people, \%flintstones;

@flint_keys=keys %flintstones;

for ($i=-1; $i < $#people; ++$i){
foreach $key (@flint_keys) {
print "$people[$i]->{$key}\n";
}
}
Ralph Grothe
Honored Contributor

Re: How to access hash values in "arrays of hases" ?

Just looking at the code there are a few things that immediately seem to fail.
As already mentioned it is strongly recommended to use the strict pragma, also warnings, and diagnostics may help.
First, we can't see what diffDateTime is expecting as arguments, and what it is returning in list context.
Let's assume that it is correctly assigning $Hrs, $Mins, Secs.
But we still don't know if the hashref $times_data is correctly defined.

Then this assignment should be put in double quotes

$loopdata{'interval'}= "$Hrs:$Mins:$Secs";

You could also use the concat operator "." which would require quoting ':'
or a join(":", $Hrs, $Mins, $Secs).

Then I am not sure what your @intlist array holds since you were pushing hashrefs of %loopdata on it.
It might have been already containing other elements, but this would be a very ugly data mix.
Better be explicit and undefine it before the the while loop over fetchrow_hashref

@intlist = ();

or

$#intlist = -1;

So if @intlist really only contains fetched elements from above then the
if statement should rather read

if ($interval[++$i]) {

Btw. are you really sure about the pre-increment of the array index $i?
Since this appears a second time,
and even a third time at the end of the loop
you may well run out of array bounds.

In Perl, C-style for loops should be avoided
(the ones where you iterate over an index like

for ($i=0; $i<=$#intlist; $i++)

better loop the Perl way like you tried

foreach my $interval (@intlist)

but then don't mix both, like you did in the loop's body later on.


These were only a few conspicous strange bits in your code snippet.
Madness, thy name is system administration
Pankaj Yadav_1
Frequent Advisor

Re: How to access hash values in "arrays of hases" ?

I have used the if($interval->[++$i]) {} statement for bounds checking but that won't work.

Can anyone tell me how can I do bounds checking in the foreach loop ?
Pankaj Yadav_1
Frequent Advisor

Re: How to access hash values in "arrays of hases" ?

In the foreach loop I am adding two values.

Please tell me the answer of the above question with reference to my CODE.
Ralph Grothe
Honored Contributor
Solution

Re: How to access hash values in "arrays of hases" ?

As for array bounds checking,
the matter in Perl is quite easy.
Referring to an array in scalar context yields its dimension, and referring to it by prepending $# to its name yields the index of its last element.
Besides, Perl lets you access the last array element (or any counting from the end) by negative indexing.

e.g.

my $dim = @intlist;
my $last_idx = $#intlist;
my $last_elem = $intlist[-1];

But if you simply foreach loop
(the same works for simply "for", but the more common idiom is foreach)
there is no need to guard your array indices.
This is also a strong pro, apart from better readability.


Madness, thy name is system administration
Pankaj Yadav_1
Frequent Advisor

Re: How to access hash values in "arrays of hases" ?

I move back to my first question.

Marvin Strong had suggested a way to access the values in the hash.
But as you can see my hash is temporary so I can't use it as suggested by Marvin.

So please look up my code and tell me how can access the {interval} values in @intlist inside the FOREACH loop.
Ralph Grothe
Honored Contributor

Re: How to access hash values in "arrays of hases" ?

foreach my $intlist_href (@intlist) {
my $interval = $intlist_href->{interval};
}
Madness, thy name is system administration