Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Data Structures / What to use

Status
Not open for further replies.

1DMF

Programmer
Jan 18, 2005
8,795
GB
Hello peeps,

I am working on a new menu system to make navigation of the members commission statements easier.It currently just shows a long list.

I have the basic menu structure done but am strugling to think of the best way to store the data to then loop and build the dynamic menu.

I have decided after speaking with the accounts bods that the menu will show the months as a static menu January - December regardless if they have a statement for that month, then a sub menu will pop out for the years 2005, 2006 etc... with a further sub menu for each statement .

so we have for example
January
|
----2005
| |
| ------ Period Ending 10/01/2005
| |
| ------ Period Ending 27/01/2005
|
----2006
| |
| ------ Period Ending 01/01/2006
February
|
----2005
and so on....

what is the best way to store this data and then loop it.

I have an array of hashes for each of the statements (a record set).

I need to build them into Month/Year.

Can I have a hash of arrays of arrays ? would that be the right approach. so i have a hash for the month, each value is an array for each year and each year is an array for each statement.

should I have an array for each month separately, which holds an array of the years which holds an array of each statement?

How would you approach this?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I've had a think and decided that a 3 dimentional array of hashes should do the job.
eg.
my @months;
$month[0][0]{Hash of statement}

So I have an array @month which has 0-11 indexes for the months, then that is an array 0-[whatever current year is] (0 is 2005, 1 is for 2006 etc..), and that contains the hash from the original record set for that statement.

now all i need is help with the syntax to create this data structure, how i populate it and how I reference it.

i assume my referencing is correct $month[0][0]{'Period'}

would give me the period ending date for January, 2005.

but how do i build this ?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
nope i just realised that won't work I need an additional array as there are more than one statement for each month/year, wow this is complicated, or am I just making it that way, how do I have a data structure like so..
$month[0][0][0]{Hash}

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
ok i've come up with this code, not tried it yet, but would appreciate some guidance if you think i've done it wrong.
Code:
# Get statements
@rs = &getSQL("Statements","AutoID,SDate,DocID,ARNo","ARNo = '$arcomp'","SDate DESC, DocID DESC");

# Set vars and array counter
my @months
my @mnames = split(/|/,"January|February|March|April|May|June|July|August|September|October|November|December");
my $i = -1;
my $curperiod = "";

# Loop Statements and build array for menu structure.
for(@rs){
    # Split date 
    my @sdate = split(/-/,substr($_->{'SDate'},0,10));
    my $thisperiod = "$sdate[1]-$sdate[2]";
    
    # Correct into index value
    my $year = $sdate[2] - 2005;
    my $mon  = $sdate[1] - 1;
           
    # Set current month/year current period array index
    if($i == -1){$curperiod = "$sdate[1]-$sdate[2]"; $i++;}
    else{if($thisperiod ne $curperiod){$curperiod = "$sdate[1]-$sdate[2]"; $i=0;};}
        
    # insert data into menu array
    $months[$year][$mon][$i] = $_;
   
    # Add one to period array index
    $i++;        
}

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Just had the quickest glance through this and, admittedly without trying too hard, have no idea what $i is for and what it does.

A variable with no obvious connection to the problem is usually a sign that code can be tightened. Sometimes the solution is just a more helpful choice of variable name but it's sometimes a pointer that some choice of data structure or algorithm could be improved.

Yours,

fish

["]As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.["]
--Maur
 
hey fishi apart from this error I just noticed,
insert data into menu array
$months[$year][$mon][$i] = $_;

should be
Code:
 insert data into menu array
    $months[$mon][$year][$i] = $_;

$i is for each statement (hash) for each month/year period.

thus needing $curperiod and thisperiod - to see if the statement is for a different month year and reset the array index counter

I thought i had commentd my code well enough - obviously not - lol. but appart from that do you see it as a solution ?

the thing is how do i then loop this to build the menu anyway

what does for(@months){} give me, would i need to then do..

Code:
my $mnth = -1;
foreach my @month(@months){]
    $mnth+;
    #do stuff for month menu option(reason for @mnames earlier on aswell so I get month names)
    print "<li>$mnames[$mnth]";
    my $yr = -1;
    foreach @year(@month){
      $yr++;
      my $dispyear = $yr + 2005;
      print"<li>$dispyear";
         foreach %stat(@year)
           print "<li><a href=\"/statements.cgi?ST=$stat{'DocID'}\"> period ending $stat{'SDate'}</a>";

and so on to build the menu, do you think i'm close ?




"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
nope that doesn't work i get this error
Missing $ on loop variable at ...
the line is
Code:
foreach my @month (@months){}
but @months is an array which holds an array isn't it or am i missing something, so i want to put the array held in each index of @months into @month so i can loop that array. hmmm, back to the drawing board!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
i can't work this out, i keep getting error
Can't coerce array into hash at

with
Code:
my $mnth = -1;
foreach my $month (@months){
    $mnth++;
    # Display Month
    print "<li>$mnames[$mnth]";
    my $yr = -1;
    foreach my $year ($month){
      $yr++;
      my $dispyear = $yr + 2005;
      print"<li>$dispyear";

         foreach my $stat($year){  
            my $i = -1;
            foreach my $st ($stat){
                $i++;
                print "<li><a href=\"/statements.cgi?ST=$$st{'DocID'}\"> period ending $$st{'SDate'}</a>";
            }
         }
    }
}

ive tried $st[$i] but that errors saying i hadn't declared @st, I don't understand how perl holds this data.

$months[0][0][0]->{'DocID'} should equal [january][2005][0]->{'DocID'}

but if i try to reference it i get this error
Can't use string ("0") as a HASH ref while "strict refs"

what on earth does that mean?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
right worked out that error i'd made a boob while defining $months[0][0][0] = %_; it should have been $_

what i don't seem to beable to do is dereference the array to get to the hash, any one?


"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I've Cracked it!
Code:
print "Content-type: text/html\n\n";
my $mnth = -1;
foreach my $month (@months){
    $mnth++;
    # Display Month
    print "<li>$mnames[$mnth]";
    my $yr = -1;
    foreach my $year (@$month){
      $yr++;
      my $dispyear = $yr + 2005;
      print"<li>$dispyear";

         foreach my $stat(@$year){  
            foreach my $st ($stat){
                print "<li><a href=\"/statements.cgi?ST=$$st{'DocID'}\"> period ending $$st{'SDate'}</a>";
            }
         }
    }
}
print "</li></li></li>";
        exit();

The html doesn't work properly this was just my test at getting the data.

the problem was the foreach my $month(@months) creates and array reference into $month so to get the next array i need to dereference the first with foreach my $year (@$month){} by putting an @ infront of the $ in the scalar, then do the same for the next level, which gives me access to the hash ref, which i then dereference in the normal way $$ (ok i could use ->) but i don't care - it works!

I've got a headache!


"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
In PERL for an n dimensional data structure all n-1 dimensions are references and have to be dereferenced as such.

Also, you should just use Lincoln Stein's CGI.pm instead of writing html. I create a lot of forms, menus and stuff and never have written a line of html.

-abir
 
I know that now - lol , hey i guess the best way to learn is banging your head till it all makes sense.

how do you create bespoke HTML including javascript with the CGI module ?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top