Hash of Arrays

D

Deepu

Hi All,

I have a problem and i am not able to get what might be a better way of

solving this. Can somebody please give me some ideas on solving this.

I have a file which have transitions like:

STATE1
STATE3
STATEMAIN ####
STATESUSPEND
STATE1
STATE2
STATERESUME
RESET
STATE6
STATE8
STATEMAIN ####
STATE9
STATE10

This indicates a transition from STATE1 to STATE3, then STATE3 to
STATEMAIN and so on. There are also 10 files which will have different
combinations of these states.

Here i need to go through the file and check for STATEMAIN and when i
see STATEMAIN, then i need to put it in an array till i see RESET or
end of file. After that again i need to proceed further to check
whether there is any more STATEMAIN. If present again i need to put it
in a different array till RESET or end of file.

I need to store it in an hash:

%hash = (
FILE1 => ["STATEMAIN", "STATESUSPEND", "STATE1",
"STATE2", "STATERESUME", "RESET"],
FILE1 => ["STATEMAIN", "STATE9", "STATE10"],
FILE2 => - - - - -
);

and also if there is no STATEMAIN in any file there is no need of
putting in the hash.

Please help me on this.

Thanks
Deep
 
J

John W. Krahn

Deepu said:
I have a problem and i am not able to get what might be a better way of
solving this. Can somebody please give me some ideas on solving this.

I have a file which have transitions like:

STATE1
STATE3
STATEMAIN ####
STATESUSPEND
STATE1
STATE2
STATERESUME
RESET
STATE6
STATE8
STATEMAIN ####
STATE9
STATE10

This indicates a transition from STATE1 to STATE3, then STATE3 to
STATEMAIN and so on. There are also 10 files which will have different
combinations of these states.

Here i need to go through the file and check for STATEMAIN and when i
see STATEMAIN, then i need to put it in an array till i see RESET or
end of file. After that again i need to proceed further to check
whether there is any more STATEMAIN. If present again i need to put it
in a different array till RESET or end of file.

I need to store it in an hash:

%hash = (
FILE1 => ["STATEMAIN", "STATESUSPEND", "STATE1",
"STATE2", "STATERESUME", "RESET"],
FILE1 => ["STATEMAIN", "STATE9", "STATE10"],

In Perl a hash cannot have two different keys with the same name.

FILE2 => - - - - -
);

and also if there is no STATEMAIN in any file there is no need of
putting in the hash.

This will put your data into a HoAoA:

my %hash;
while ( <> ) {
push @{ $hash{ $ARGV } }, [] if /STATEMAIN/;
push @{ $hash{ $ARGV }[ -1 ] }, $_ if /STATEMAIN/ .. /RESET/ || eof;
}

use Data::Dumper;

print Dumper \%hash;




John
 
T

Tad McClellan

John W. Krahn said:
Deepu wrote:
%hash = (
FILE1 => ["STATEMAIN", "STATESUSPEND", "STATE1",
"STATE2", "STATERESUME", "RESET"],
FILE1 => ["STATEMAIN", "STATE9", "STATE10"],

In Perl a hash cannot have two different keys with the same name.


Can a hash have two different keys with the same name somewhere
besides in Perl?

How do you distinguish between the two?

How does the hashing differ?

Should I take this off-topic question elsewhere? :)
 
D

Deepu

Hi All,

Thanks a lot for helping me on this.I tried the above code and got one
problem. I was trying to countthe STATESUSPEND if located between
STATEMAIN and RESET.

STATE1
STATE3
STATEMAIN ####
STATESUSPEND
STATE1
STATE2
STATERESUME
RESET
STATE6
STATE8
STATEMAIN ####
STATE9
STATE10

Code:

use strict;
use Data::Dumper;


my @files = qw/FILE1 FILE2/;


my %transitions;
my %hashsuspend


foreach my $filename (@files)
{
my $fh;
open $fh, $filename
or do {
warn "$filename missing";
next;
};


my $run_through = 0;
my $recording_enabled = 0;
while (<$fh>)
{
if (/^RESET\b/)
{
$recording_enabled = 0;
}
elsif (/^STATEMAIN\b/)
{
$run_through++;
$recording_enabled = 1;
$suspendCount =0;
}
elsif ($recording_enabled)
{
push @{$transitions{$filename}[$run_through]}, $_;
if ($_ =~ /^STATESUSPEND/)
{
$suspendCount++;
$hashsuspend{$filename}[$run_through] = $suspendCount;
next;
}
}
}
close $fh or die $!;

}


print Dumper \%transitions;
print Dumper \%hashsuspend;

The output i am getting with this is:

%transitions = (
FILE1 => [
undef,
[
STATESUSPEND
STATERESUME
STATE1
STATE2
],
and so on.

What is the reason for undef at the start of the array in every
file.This undef appears even with hashsuspend. Please help me on this.

Thanks
Deep

Tad said:
John W. Krahn said:
Deepu wrote:
%hash = (
FILE1 => ["STATEMAIN", "STATESUSPEND", "STATE1",
"STATE2", "STATERESUME", "RESET"],
FILE1 => ["STATEMAIN", "STATE9", "STATE10"],

In Perl a hash cannot have two different keys with the same name.


Can a hash have two different keys with the same name somewhere
besides in Perl?

How do you distinguish between the two?

How does the hashing differ?

Should I take this off-topic question elsewhere? :)
 
J

John W. Krahn

Deepu said:
Thanks a lot for helping me on this.I tried the above code and got one
problem. I was trying to countthe STATESUSPEND if located between
STATEMAIN and RESET.

STATE1
STATE3
STATEMAIN ####
STATESUSPEND
STATE1
STATE2
STATERESUME
RESET
STATE6
STATE8
STATEMAIN ####
STATE9
STATE10

Code:

use warnings;
use strict;

@ARGV = qw/FILE1 FILE2/;

my ( $suspendCount, %transitions );

while ( <> ) {

push @{ $transitions{ $ARGV } }, [] if /STATEMAIN/;

if ( /STATEMAIN/ .. /RESET/ || eof ) {

push @{ $transitions{ $ARGV }[ -1 ] }, $_;

$suspendCount += /STATESUSPEND/;

}
}

__END__



John
 
P

Peter J. Holzer

Tad said:
John W. Krahn said:
Deepu said:
%hash = (
FILE1 => ["STATEMAIN", "STATESUSPEND", "STATE1",
"STATE2", "STATERESUME", "RESET"],
FILE1 => ["STATEMAIN", "STATE9", "STATE10"],

In Perl a hash cannot have two different keys with the same name.


Can a hash have two different keys with the same name somewhere
besides in Perl?

Depends on what you mean by "hash". A hash table can, since it needs to
handle hash collisions, too. An associative array cannot, since it uses
the key as a unique index.
How do you distinguish between the two?

Several possibilities: E.g., address or key plus serial number.
How does the hashing differ?

It doesn't. You have several entries with the same hash value, but you
have that with unique keys, too.
Should I take this off-topic question elsewhere? :)

Possibly :)

hp
 
D

Deepu

Hi James,

I tried the correction you had specified but i am still getting that
'undef'.

I am getting the output like:

%hash = (
FILE1 => [
undef,
[
STATESUSPEND
STATERESUME
STATE1
STATE2
],
[
_
_
]
],
FILE2 => [
undef,
[
_
and so on

Thanks a lot for helping me on this.

--Deep






Tad said:
John W. Krahn said:
Deepu wrote:
%hash = (
FILE1 => ["STATEMAIN", "STATESUSPEND", "STATE1",
"STATE2", "STATERESUME", "RESET"],
FILE1 => ["STATEMAIN", "STATE9", "STATE10"],

In Perl a hash cannot have two different keys with the same name.


Can a hash have two different keys with the same name somewhere
besides in Perl?

Depends on what you mean by "hash". A hash table can, since it needs to
handle hash collisions, too. An associative array cannot, since it uses
the key as a unique index.
How do you distinguish between the two?

Several possibilities: E.g., address or key plus serial number.
How does the hashing differ?

It doesn't. You have several entries with the same hash value, but you
have that with unique keys, too.
Should I take this off-topic question elsewhere? :)

Possibly :)

hp

--
_ | Peter J. Holzer | Man könnte sich [die Diskussion] auch
|_|_) | Sysadmin WSR/LUGA | sparen, wenn man sie sich einfach sparen
| | | (e-mail address removed) | würde.
__/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15
 
T

Tad McClellan

Hi James,

Huh?


Thanks a lot for helping me on this.


Please learn the proper way of composing a followup.

Please do this very very soon.



Errr, no "James" there...



[snip the rest of the vile TOFU]
 
D

Deepu

Hi John,

I was trying your code and had a question regarding that.

use warnings;
use strict;

@ARGV = qw/FILE1 FILE2/;


my ( $suspendCount, %transitions );


while ( <> ) {


push @{ $transitions{ $ARGV } }, [] if /STATEMAIN/;


if ( /STATEMAIN/ .. /RESET/ || eof ) {


push @{ $transitions{ $ARGV }[ -1 ] }, $_;


$suspendCount += /STATESUSPEND/;


}
}


__END__


I changed the file (input file):

STATE1 blk: 10 pg:10
STATE3 blk:11 pg:100
STATEMAIN #### blk: 100 pg: 20
STATESUSPEND
STATE1
STATE2
STATERESUME
RESET
STATE6
STATE8
STATEMAIN ####
STATE9
STATE10

and all the states will have blk and pg numbers.

But when i changed the script for just taking state names and blk
numbers. I get 'undef' in the output.

@ARGV = qw/FILE1 FILE2/;


my ( $suspendCount, %transitions );

while ( <> ) {

if ($_ =~ /^\s*(\S+\t+blk:\s+\S+)\s+pg:\s+(\S+)/) {

push @{ $transitions{ $ARGV } }, [] if /STATEMAIN/;


if ( /STATEMAIN/ .. /RESET/ || eof ) {


push @{ $transitions{ $ARGV }[ -1 ] }, $1; #### $_ changed to
$1


$suspendCount += /STATESUSPEND/;


}
}
}

__END__


Now i get the output:

$VAR1 = (
FILE1 => [
[
undef,

STATESUSPEND
STATE1,
STATE2,
STATERESUME,

undef
],
and so on.

In the array STATEMAIN and RESET is undef after the changes, why is
this?? Thanks for helping me on this.
 
M

Mumia W.

Deepu said:
[...]
if ($_ =~ /^\s*(\S+\t+blk:\s+\S+)\s+pg:\s+(\S+)/) { <--- Line 1

push @{ $transitions{ $ARGV } }, [] if /STATEMAIN/;


if ( /STATEMAIN/ .. /RESET/ || eof ) { <--- Line 2


push @{ $transitions{ $ARGV }[ -1 ] }, $1; #### $_ changed to
$1
[...]

In the array STATEMAIN and RESET is undef after the changes, why is
this?? Thanks for helping me on this.

Whenever a successful match occurs, and no capturing was done, the match
variables are reset.

On line 2, when /STATEMAIN/ (or /RESET/) is successful, the match
variables $1 and $2 are reset. IOW (in other words), the data captured
from line 1 is lost at line 2, so you need to save the values in other
variables before you get to line 2.
 
D

Deepu

Thank you all for helping me out on Hash of array of arrays. I was able
to print out without 'undef' as the array was starting at 1 always and
not 0.


Deepu said:
[...]
if ($_ =~ /^\s*(\S+\t+blk:\s+\S+)\s+pg:\s+(\S+)/) { <--- Line 1

push @{ $transitions{ $ARGV } }, [] if /STATEMAIN/;


if ( /STATEMAIN/ .. /RESET/ || eof ) { <--- Line 2


push @{ $transitions{ $ARGV }[ -1 ] }, $1; #### $_ changed to
$1
[...]

In the array STATEMAIN and RESET is undef after the changes, why is
this?? Thanks for helping me on this.

Whenever a successful match occurs, and no capturing was done, the match
variables are reset.

On line 2, when /STATEMAIN/ (or /RESET/) is successful, the match
variables $1 and $2 are reset. IOW (in other words), the data captured
from line 1 is lost at line 2, so you need to save the values in other
variables before you get to line 2.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top