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

I apologize for my complex code, but my question does not concern most of it. My problem is putting elements into an array. Right now I have a 3D array of which x->y->z, x points to a list of y's and each y points to a list of 6 values. What I am trying to do is sort just a part of the y list. I need to get y elements out, sort them and then put them back into the big array, in order. Here is my jumbled code. Again, I apologize, but if you could just concentrate on the array assignments and referencing. I am trying to pull out x and y values (that's what  $blocks[$i][$l][1] = x, $blocks[$i][$l][2] = y are. I am trying to find the distance from these points to the solid vertex before it (solid vertex is  $blocks[$i][$k][4] == 88888 I also included a sample of the big array. If  [$i][$j][4] == 88888 then it is a solid vertex. I am trying to sort the points in between these solid vertex. i.e.  [0][2][4] = 0 and  [0][3][4] = 0 so I am trying to sort these two relative to their distance from the first solid vertex  [0][1][4] = 88888 a solid vertex. Any help with the referencing of the arrays would be great. I tried to use the DUmper, but I could not tell where things were. My errors are uninitiated value. Here is my code
for $k (($j+1)..$#{$blocks[$i]}) { if ($blocks[$i][$k][4] == 88888) { my @a; for $l (($j + 1)..($k - 1)) { $a[$l][1] = $blocks[$i][$l][1]; $a[$l][2] = $blocks[$i][$l][2]; } push @aa, \@a; for my $pp (($j + 1)..($k - 1)) { print "[$pp][1] => $aa[$pp][1]\n"; print "[$pp][2] => $aa[$pp][2]\n"; } my @d; for $m (($j + 1)..($k - 1)) { my $e3 = $aa[$m][1]; print " $e3\n"; $d[$m][1] = sqrt((($aa[$m][1] - $blocks[$i][$m +][1])*($aa[$m][1] - $blocks[$i][$m][1])) + (($aa[$m][1] - $blocks[$i] +[$m][1])*($aa[$m][1] - $blocks[$i][$m][1]))); $d[$m][2] = $m; } push @dd, \@d; my @sortedist = sort { $a -> [1] <=> $b -> [1] } @ +dd; for $n (($j + 1)..($k - 1)) { $temp = $blocks[$i][$n]; $blocks[$i][$n] = $blocks[$i][($sortedist[$n][ +2])]; $blocks[$i][($sortedist[$n][2])] = $blocks[$i] +[$n];
[0][0][0] =>1 [0][0][1] =>515.438792 [0][0][2] =>2167.220067 [0][0][3] =>0 [0][0][4] =>88888 [0][0][5] =>99999 [0][0][6] =>99999 [0][1][0] =>2 [0][1][1] =>535.930414 [0][1][2] =>2240.612915 [0][1][3] =>0 [0][1][4] =>88888 [0][1][5] =>99999 [0][1][6] =>99999 [0][2][0] =>3 [0][2][1] =>1123.073200 [0][2][2] =>2076.679934 [0][2][3] =>0 [0][2][4] =>0 [0][2][5] =>99999 [0][2][6] =>99999 [0][3][0] =>4 [0][3][1] =>1102.581578 [0][3][2] =>2003.287086 [0][3][3] =>0 [0][3][4] =>0 [0][3][5] =>99999 [0][3][6] =>99999 [0][4][0] =>5 [0][4][1] =>515.438792 [0][4][2] =>2167.220067 [0][4][3] =>0 [0][4][4] =>88888 [0][4][5] =>99999 [0][4][6] =>99999

Replies are listed 'Best First'.
Re: Building an array
by graff (Chancellor) on Feb 15, 2003 at 18:58 UTC
    Getting a report of "uninitialized value" could be a problem with how the "blocks" array is being created/filled in the first place -- no gaurantee that the cause of that error will be found in this portion of your code.

    Apart from that, it will be better for you to try dereferencing the values that you need for doing the distance arithmetic before you actually do the arithmetic -- that way, when you hit the "uninitialized" error, it will be on a specific line of code where you are trying to dereference a particular value, and then it will be possible to trace back to where you thought that value was being stored (but in fact was not).

    Also, it looks like you've been using the "copy/paste" approach to programming -- almost never a good idea, because (1) it means you're not factoring the problem properly to reduce redundant code and (2) you'll sometimes forget to make the small changes relative to the chunk that you copied from, or you'll make the wrong changes. In this case, the values being used in that lengthy "sqrt(...)" call are all the same, and if you didn't have an array reference problem, you'd have a math error (can't do sqrt on zero).

    Let's see if I can paraphrase what you're trying to do here -- note that this is how I would begin any perl script: start with commentary to describe what's going on:

    # * GIVEN: an AoAoA (@blocks), where: # -- the outermost index is (I think) a set of objects (?), # ---- the second index is a set of vertices for each object, # ------ the third index is a set of six values for each vertex: # ID(?), x, y, z(?), type-flag, another-flag(?), yet-another-flag(?). # When the type-flag is "88888", this is a solid vertex. # * TO DO: go through the vertices of each object in sequence # -- if the vertex is solid, store its x,y coordinates in @base # -- otherwise, store its x,y coordinates in $remote[0] (AoA) and: # ---- looking ahead while next vertex is also not solid, # push next set of coordinates onto @remote # ---- if more than one set of coordinates in @remote: # ------- foreach (@remote) # ---------- compute distance from @base and push it onto this x,y arr +ay # ------- for the elements of @remote sorted by distance: # --------- copy the coordinates from this element back to # the current vertex of @{$blocks[$thisObj]} # --------- increment to the next vertex in @{$blocks[$thisObj]}
    Of course, there are other ways to go about it, but if I understand your post, this approach should do what you want, and I hope the description is clear enough that you can see the way to code it.