http://www.perlmonks.org?node_id=1014730

reaper9187 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Everyone ..
Back here to seek your wisdom on a particular issue. I'm trying to develop a time based analysis of a system monitoring certain parameters. I need to display the information using line graphs. I'm currently using Tk::Chart for this purpose. As it turns out , evry line graph i will be plotting is a function of three variables(say A,B,C).
As you all must be aware, Tk::Chart only uses array references for displaying data( assuming the hash references do not exist), i need to customize my data accordingly.
I'm trying to create an array of 2D arrays, something like push(@{($a[$i])[$j][$k]},,44,55,66,22); #but this is not allowed
For eg: @a = qw/1 2 3 4 5/; , where each element has a 2D array associated with it ..

please help ..!!

Replies are listed 'Best First'.
Re: Multidimensional arrays within arrays
by Kenosis (Priest) on Jan 22, 2013 at 19:09 UTC

    Perhaps the following structure would be helpful:

    use strict; use warnings; use Data::Dumper; my @list = 1 .. 15; my @array; my $i = 1; while ( my ( $i, $j, $k ) = splice @list, 0, 3 ) { push @array, [ [ $i, $j, $k ], [ 44, 55, 66, 22 ] ]; } for my $arr (@array) { print "@{ $arr->[0] }: @{ $arr->[1] }\n"; } print "\n", Dumper \@array;

    Output:

    1 2 3: 44 55 66 22 4 5 6: 44 55 66 22 7 8 9: 44 55 66 22 10 11 12: 44 55 66 22 13 14 15: 44 55 66 22 $VAR1 = [ [ [ 1, 2, 3 ], [ 44, 55, 66, 22 ] ], [ [ 4, 5, 6 ], [ 44, 55, 66, 22 ] ], [ [ 7, 8, 9 ], [ 44, 55, 66, 22 ] ], [ [ 10, 11, 12 ], [ 44, 55, 66, 22 ] ], [ [ 13, 14, 15 ], [ 44, 55, 66, 22 ] ] ];

    A reference to a reference to three values from @list and a reference to a four-element list is push onto @array. The for loop iterates through the list of references, and prints their dereferenced values. A dump of @array shows the structure.

    Within the for loop, elements can be access as follows:

    [ [ $i, $j, $k ], [ 44, 55, 66, 22 ] ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | | | | | | | | | | + - $arr->[1][3] | | | | | | | | + - $arr->[1][2] | | | | | | | + - $arr->[1][1] | | | | | | + - $arr->[1][0] | | | | | + - $arr->[1] | | | | + - $arr->[0][2] | | | + - $arr->[0][1] | | + - $arr->[0][0] | + - $arr->[0] + - $arr
Re: Multidimensional arrays within arrays
by Anonymous Monk on Jan 22, 2013 at 16:59 UTC
Re: Multidimensional arrays within arrays
by reaper9187 (Scribe) on Jan 23, 2013 at 08:19 UTC
    Thank you everyone for their suggestions.. Some smart manipulation of the data helped me get rid of this problem but a new problem has cropped up. I have grouped the data together and referenced the array as push(@{$variable[0]}, #some values);
    But the value $variable is generated within the subroutine and i need to export this information to some other subroutine that is called by the user ( to plot the graph). As such, i was thinking of defining these arrays as global variables so that it can be easily accessed by the user without having to call the parent subroutine which generates these arrays(after first run). For eg: SubA generates these arrays. I need to call sub B(called by another subroutine C) that plots the graphs

    Currently, i am able to generate the graphs within the same subroutine. I need to globalize these arrays.I cannot pass these arrays as arguments to sub C directly. My problem is with defining these dereferenced hashes(eg: @{$variable[0]}) within Sub A as global variables . How do i do that ???

      Why can't you pass the coordinates to sub C?

      And do you call sub B, or does sub C call sub B? I think I'm distilling the notion that you want C to call B, am I right? Let's roll with that.

      Why would this not work for you?

      sub subA { # ... # generate array; # here be dragons, an' arrays an' pushes an' references # an' lots of dereferencing happens here, me lad. # ... return \@array; } sub subB { my $chart_widget = shift; my $data_aref = shift; $chart_widget->chart( $data_aref ) # or however Tk::Chart be used, + matey } sub subC { my $chart_widget = shift; my $data_aref = shift; # ... # I don't have a clue what be happenin' here, me hearty. # ... subB($chart_widget, $data_aref); }

      And from your main code:

      my $chart = $mw->Chart( ... ); my $data_aref = subA; subC($chart, $data_aref);
Re: Multidimensional arrays within arrays
by Anonymous Monk on Jan 23, 2013 at 03:19 UTC
    Remember this: even though the "array" data-structure in Perl is "only one-dimensional," each element in this (or any other type of ...) data structure can be a reference to "anything at all." Therefore, you can construct data structures of arbitrary complexity. "Multi-dimensional arrays" are the least of what you can do.
Re: Multidimensional arrays within arrays
by reaper9187 (Scribe) on Jan 23, 2013 at 17:13 UTC
    Thank you muba for the suggestion. I've reformulated the problem to the simplest level. See if you can figure out what is wrong. Following is the sample code

    sub A { ... foreach $key(@some array) # eg: array contains values like Sunday, Mon +day , Tuesday..etc { ... ... ... push(@{$key[0]}, #some values); #create dereferenced array push(@{$key[1]}, #some values); #eg: Monday has # @Monday = ([1,23,4,8,], + # [12,58,77,9]); .. .. # what do i do here ?? } sub B #to be called by the user after running the sub A for the first +time { .. print "Enter the day to be plot: "; $a = <>; #this value is to be matched to the array name i.e Monday to + be plotted, .. # once the corresponding array is found , we plot the values + }
    I'm thinking of the following solns :

    1. Save the references for each of these dereferenced arrays as a variable and save it as a separate array and make the array global (or return it to the parent function and make it global)
    2. Save each of the dereferenced arrays as global variables and try to access using Sub B ( what i have been trying but no luck so far).

    Please suggest.. ( I'm new to perl .. I'm sorry if the above points seem foolish)..
    Update: I think the naming convention for the array variable seems to be causing the issue Coz when i try to return the references for each of the arrays , it gives me the same scalar value(reference ) for different elements.. I need a way out of this and quick .!! Please help
Re: Multidimensional arrays within arrays
by reaper9187 (Scribe) on Jan 23, 2013 at 20:37 UTC
    Ok .. so here is the part i feel ,if resolved will completely solve my problem .
    @a = qw/Mon Tue Wed Thurs/; foreach $key(@a) { push(@$key, $key); print Dumper(\@$key); }
    The only problem with the above code is the array variable. Now there occur three possibilities
    #Declare array as push(@$key, #some values); .. .. #The above code will help me to generate different arrays for multiple + variables but it does not help me to create a multi-dimensional arra +y( Note: I cannot use an anonymous array here since i need to reitera +te the entire loop over several days to measure performance and i cou +ldnt find a way of pushing elements on to an anonymous array without +creating a separate reference for it) 2. #Declare array as push(@{$key[0]}, #some values); .. .. #Alhtough this will help me to get the desired array format , however +the most irritating part is that the variable $key is constant ,i.e e +vn if i iterate it over a loop, only one array ( i.e @key is generate +d and the reference for all the arrays is the same)
    So, basically i am looking to create multiple arrays with the required references( multiple dimensions ,eg 2D).. Please help ..!!! I'm getting desperate now