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

I am having a mental block on how to handle data I have in a text file which contains partial data of 3 dimension coordinates of mulitple points.

an example for a triangle on the xy plane: --------------------- sect_name line-aa sect_plane xy sect_num 4 1 1 2 1 2 2 1 2 --------------------

The sect_plane value identifies how the points are orderd, in this case fist x then y. I am trying to put the data into a data structure  [seq][x][y][z] not sure if this is a good use for HASH or not.

I use a hash list to store the header information, not sure how to store the point coordinates, for each point I need its "sequence number, x, y, z" values in that order./p>

Can a hash be used for more than just one key/value pair?

Any ideas? Sal

Replies are listed 'Best First'.
Re: Managing structured data
by kcott (Archbishop) on Jun 10, 2012 at 20:01 UTC
    Can a hash be used for more than just one key/value pair?

    Yes it can and typically does.

    You might want to consider using a hash like this to store your point coordinates:

    { x => 0, y => 0, z => 0, seq_no => N, }

    -- Ken

Re: Managing structured data
by ww (Archbishop) on Jun 10, 2012 at 20:27 UTC
    Some of us may be -- uh, challenged -- (well, /me certainly is) by the lack of an explicit declaration that sect_num, eg, 4, is the z value... or that z has some other value...OR that it's the mystery-value you're referring to with the phrase "partial data." Then too, the [seq], in your problem statement, has an undefined value (Halp! Where's it come from?)

    All that whining aside, why not an AoA?

    my @AoA = (["seq1", 1, 1, 4], ["seq2", 2, 1, 4], ["seq3", 2, 2, 4], ["seq4", 1, 2, 4], );
      AoH is better, probably, because you can't easily see throughout your code whether you should be querying the 2nd or the 4th slot in the array to do this-or-that ... and every statement is now completely dependent on the order that you initially chose, and there WILL be a bug in there somewhere. But if the array-element is a hash, the array-element is now self-describing. Each slot is named.
        Excellent point!
Re: Managing structured data
by salp (Novice) on Jun 10, 2012 at 20:53 UTC
    This is the code I have written, Many of the variables are not being used yet.
    #!/usr/bin/perl use strict; use warnings; use Getopt::Long; my $sect_name = ""; # Name of section my $sect_unit = ""; # Units defaults to inches my $sect_depth = 0; # Distance from origin my $sect_plane = ""; # Plane, defaults to X-Y plane my $sect_num = 0; # Number of points my $file_name; my $fh; my $help = 0; my $_debug = 0; my $val1 = 0; my $val2 = 0; my %vector_hdr; # Headr information hash list my @vector_pts = (); # Array of x,y coordinates my $vector_str = ""; # my $top = 'xy'; my $bottom = 'yx'; my $right = 'zy'; my $left = 'yz'; my $front = 'zx'; my $back = 'xz'; GetOptions( 'file_name=s' => \$file_name, 'sect_name' => \$sect_name, 'sect_unit' => \$sect_unit, 'sect_depth' => \$sect_depth, 'sect_plane' => \$sect_plane, 'sect_num' => \$sect_num, 'help' => \$help, 'debug' => \$_debug, ); if(!$file_name){ print "No file was specified $!\n"; help(); exit; } #open file open($fh, $file_name) or die "Failed to open file $file_name: $!"; #process file content my $line_in; my $key; my $value; my $seq_num = 0; my $max = 0; my $plane; my $coord_x; my $coord_y; my $coord_z; while($line_in = <$fh>){ chomp $line_in; if($_debug){print "processing: $line_in\n";} if($line_in =~ m/^sect_/){ ($key, $value) = split(' ', $line_in); $vector_hdr{ $key } = $value; } else { # Put coordinates into 3D array # need test to skip lines with no data ($val1, $val2) = split(' ', $line_in); if($vector_hdr{'sect_plane'} =~ m/xy/){ $vector_pts[$seq_num][1] = $val1; $vector_pts[$seq_num][2] = $val2; $vector_pts[$seq_num][3] = $vector_hdr{'sect_depth'}; } # plot on front plane if($vector_hdr{'sect_plane'} =~ m/zx/){ $vector_pts[$seq_num][1] = $val2; $vector_pts[$seq_num][2] = $vector_hdr{'sect_depth'}; $vector_pts[$seq_num][3] = $val1; } # Plot on side plane if($vector_hdr{'sect_plane'} =~ m/zy/){ $vector_pts[$seq_num][1] = $vector_hdr{'sect_depth'}; $vector_pts[$seq_num][2] = $val2; $vector_pts[$seq_num][3] = $val1; } $seq_num = $seq_num + 1; } } exit;