Hash of Arrays

Discussion in 'Perl Misc' started by Deepu, Jun 23, 2006.

  1. Deepu

    Deepu Guest

    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
     
    Deepu, Jun 23, 2006
    #1
    1. Advertising

  2. Deepu wrote:
    >
    > 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
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Jun 23, 2006
    #2
    1. Advertising

  3. John W. Krahn <> wrote:
    > 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? :)


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jun 23, 2006
    #3
  4. Deepu

    Deepu Guest

    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 McClellan wrote:
    > John W. Krahn <> wrote:
    > > 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? :)
    >
    >
    > --
    > Tad McClellan SGML consulting
    > Perl programming
    > Fort Worth, Texas
     
    Deepu, Jun 24, 2006
    #4
  5. Deepu wrote:
    >
    > 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
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Jun 24, 2006
    #5
  6. Tad McClellan wrote:
    > John W. Krahn <> wrote:
    >> 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
    | | | | würde.
    __/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15
     
    Peter J. Holzer, Jun 24, 2006
    #6
  7. Deepu

    Deepu Guest

    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







    Peter J. Holzer wrote:
    > Tad McClellan wrote:
    > > John W. Krahn <> wrote:
    > >> 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
    > | | | | würde.
    > __/ | http://www.hjp.at/ | -- Ralph Angenendt in dang 2006-04-15
     
    Deepu, Jun 24, 2006
    #7
  8. Deepu <> wrote:


    > 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.


    > Peter J. Holzer wrote:
    >> Tad McClellan wrote:
    >> > John W. Krahn <> wrote:
    >> >> Deepu wrote:



    Errr, no "James" there...



    [snip the rest of the vile TOFU]

    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jun 24, 2006
    #8
  9. Deepu

    Deepu Guest

    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.
     
    Deepu, Jun 26, 2006
    #9
  10. Deepu

    Mumia W. Guest

    Deepu wrote:
    > [...]
    > 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.
     
    Mumia W., Jun 26, 2006
    #10
  11. Deepu

    Deepu Guest

    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.



    Mumia W. wrote:
    > Deepu wrote:
    > > [...]
    > > 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.
     
    Deepu, Jun 26, 2006
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Philipp
    Replies:
    21
    Views:
    1,190
    Philipp
    Jan 20, 2009
  2. rp
    Replies:
    1
    Views:
    595
    red floyd
    Nov 10, 2011
  3. Adam Akhtar
    Replies:
    5
    Views:
    678
    Adam Akhtar
    Mar 25, 2008
  4. Älphä Blüë

    Hash of Hash of Arrays Question

    Älphä Blüë, Jul 18, 2009, in forum: Ruby
    Replies:
    5
    Views:
    689
    Älphä Blüë
    Jul 18, 2009
  5. Tore Aursand
    Replies:
    3
    Views:
    579
    Anno Siegel
    Sep 16, 2003
Loading...

Share This Page