traversing a hash two using serveral conditions

Discussion in 'Perl Misc' started by Me, Jan 19, 2006.

  1. Me

    Me Guest

    I have an array of hash with the contains some of the following data:
    Direction
    Name
    Usage
    Day
    Month
    Year
    Protocol


    From this, I need to get an array of a"Usage" data for a given
    "Protocol" for a x number of "Day"(s), two direcions.

    Protocol1 = [45, 67 ,87, 76, 75] : Would be usage for
    5 day for "Protocol1".


    Snippet of what I have so far:
    ################
    foreach my $p(@$protocols) {

    foreach my $c ($day1..$day2) {

    foreach my $ref (@usage) { #the array with the data
    my $day = $ref->{Day};
    if ($day == $) {
    push(@in_proto,$ref->{Usage})
    if ($ref->{direction} eq "In");
    push(@out_proto,$ref->{Usage})
    if ($ref->{direction} eq "Out");

    }

    }

    }

    }
    ################


    Am I going in the right direction?
     
    Me, Jan 19, 2006
    #1
    1. Advertising

  2. Me wrote:
    > I have an array of hash with the contains some of the following data:
    > Direction
    > Name
    > Usage
    > Day
    > Month
    > Year
    > Protocol
    >


    Hi - that isn't a very good description of your data structure. We would
    need to see an exact sample of your data, eg as per the output of
    Data::Dumper. The smallest subset possible that fully demonstrates the
    structure would be fine.

    >
    > From this, I need to get an array of a"Usage" data for a given
    > "Protocol" for a x number of "Day"(s), two direcions.
    >
    > Protocol1 = [45, 67 ,87, 76, 75] : Would be usage for
    > 5 day for "Protocol1".
    >
    >
    > Snippet of what I have so far:
    > ################
    > foreach my $p(@$protocols) {
    >
    > foreach my $c ($day1..$day2) {
    >
    > foreach my $ref (@usage) { #the array with the data
    > my $day = $ref->{Day};
    > if ($day == $) {
    > push(@in_proto,$ref->{Usage})
    > if ($ref->{direction} eq "In");
    > push(@out_proto,$ref->{Usage})
    > if ($ref->{direction} eq "Out");
    >
    > }
    >
    > }
    >
    > }
    >
    > }
    > ################
    >
    >
    > Am I going in the right direction?


    syntax error at - line 9, near ")
    if"
    syntax error at - line 17, near "}"
    Execution of - aborted due to compilation errors.

    You need to copy and paste working code, preferably with

    use strict;
    use warnings;

    at the top.

    Mark
     
    Mark Clements, Jan 19, 2006
    #2
    1. Advertising

  3. Me <> wrote:


    > Snippet of what I have so far:



    If you say so.


    > if ($day == $) {

    ^^
    ^^ what's that?


    Post real code if you want real help.

    Have you seen the Posting Guidelines that are posted here frequently?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jan 20, 2006
    #3
  4. Me

    Anno Siegel Guest

    Me <> wrote in comp.lang.perl.misc:
    > I have an array of hash with the contains some of the following data:
    > Direction
    > Name
    > Usage
    > Day
    > Month
    > Year
    > Protocol
    >
    >
    > From this, I need to get an array of a"Usage" data for a given
    > "Protocol" for a x number of "Day"(s), two direcions.
    >
    > Protocol1 = [45, 67 ,87, 76, 75] : Would be usage for


    This would all be much clearer if you had provided a few lines of
    example data.

    > Snippet of what I have so far:


    Please don't post a snippet, post code that we can run and test.
    Your code references variables that are nowhere set. How, do you
    suppose, should we tell if what you do is right when we don't know
    what you are doing?

    > ################
    > foreach my $p(@$protocols) {


    What is in @$protocols? In fact, since you are never using $p in the
    code, why is the loop there at all?

    >
    > foreach my $c ($day1..$day2) {


    You are making a lot of passes over @usage: The number of protocols
    times the number of days. You should make one pass and extract the
    data you need as they come by.

    > foreach my $ref (@usage) { #the array with the data
    > my $day = $ref->{Day};
    > if ($day == $) {

    ^
    Is this supposed to be $c? As it stands, it is a syntax error.

    > push(@in_proto,$ref->{Usage})
    > if ($ref->{direction} eq "In");
    > push(@out_proto,$ref->{Usage})
    > if ($ref->{direction} eq "Out");
    >
    > }
    >
    > }
    >
    > }
    >
    > }
    > ################
    >
    >
    > Am I going in the right direction?


    I don't know, since neither your prose nor your code make entirely
    clear what it is you want. It looks terribly inefficient, but that
    may not be a problem.

    If I understand your intention, this is one way to do it:

    # Set up raw data
    my @usage;
    while ( <DATA> ) {
    @{ $usage[ @usage]}{ qw(
    Direction
    Name
    Usage
    Day
    Month
    Year
    Protocol)
    } = split;
    }

    # This hash points to the two possible output arrays
    my %inout = (
    In => \ my @in_proto,
    Out => \ my @out_proto,
    );

    # Define protocols to watch
    my %proto = (
    Protocol1 => 1,
    Protocol2 => 1,
    );

    # Define days to watch
    my ( $day1, $day2) = ( 1, 14);

    # Extract usage data
    push @{ $inout{ $_->{ Direction}} }, $_->{ Usage} for
    grep $proto{ $_->{ Protocol}},
    grep +( $day1 <= $_->{ Day} and $_->{ Day} <= $day2),
    @usage;

    print "In: (@in_proto)\n";
    print "Out: (@out_proto)\n";

    __DATA__
    In Donald 45 12 6 2000 Protocol1
    In Susy 67 12 6 2000 Protocol1
    In Gerald 87 12 7 2000 Protocol1

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Jan 20, 2006
    #4
    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. Stan
    Replies:
    6
    Views:
    536
    John Saunders
    Aug 22, 2003
  2. thomson
    Replies:
    0
    Views:
    328
    thomson
    Dec 27, 2005
  3. Stephen Miller
    Replies:
    1
    Views:
    296
    Alessandro Zifiglio
    Jan 2, 2004
  4. JimmySlam
    Replies:
    1
    Views:
    111
    Evertjan.
    Apr 10, 2006
  5. rp
    Replies:
    1
    Views:
    555
    red floyd
    Nov 10, 2011
Loading...

Share This Page