Slice of Array of Objects
Trying to rearrange the selected nodes in a scene and group them by the number tagged at the end of the label. Also trying to do this without having to loop thru those selected nodes too many times. So I build a sparce array:
var aSelectedNodes = new Array(nSelectedNodes);
With my current test data that wil set it to 30 items, but the loop will only fill it with six objects that have four nodes each.
While trying to get rid of most of the empty array I don't need, I did this, sliced out the non-empty items in the array:
var aGroups = aSelectedNodes.slice(0,nTrueLength); print("aGroups.length ["+aGroups.length+"]");
I got a length back, so a thing happened, if not quite what I want. Because the objects inside the array don't seem entirely defined anymore; I get an error trying to access one of the objects inside the array.
Script Error: Line 149
TypeError: Result of expression 'aGroups[ndx]' [undefined] is not an object.
Stack Trace: ()@D:/OneDrive/3D Content/MyDazNav/Scripts/Gollor/Expand Adamasen Level.dsa:149
149: aGroups[ndx].oFrontzone.oOldPos = aGroups[ndx].oFrontzone.oNode.getWSPos();
If I understand the error it's saying that either the object inside the array item got borked, or one of the subobjects of that object got borked.
So I'm wondering what should I expect the slice function to do when it's working with an array of objects of objects of objects?
Comments
The simplest explanation is that your index into the array aGroups is referencing a position that doesn't contain an object, though you expect it to contain an object. I would check the value of ndx, and the type of aGroups[ndx], if you haven't done so already, even if just to rule out the obvious.
I presume the slice() method in Daz script behaves like Javascript and returns a new array that does not include the end position.
I too would presume that the slice() method would work in a similar way to JavaScript. I would further presume it works like the documentation on the Daz Script Array.slice(). Although I'm not sure that's what's happening here.
I added some additional debugging code as you suggested:
groups of zones [30]
Script Error: Line 150
TypeError: Result of expression 'aGroups[ndx]' [undefined] is not an object.
Stack Trace: ()@D:/OneDrive/3D Content/MyDazNav/Scripts/Gollor/Expand Adamasen Level.dsa:150
But it told me pretty much what I already knew, that the contents of the aGroups Array, isn't what I think it should be. In fact I would have expected the typeof operator to indicate aGroups was an Array, not an Object.
nTrueLength in the slice function is +1 the number of items from the list I want.
Are you expecting the objects in the array to be a defined object? I don't see anywheer you are specifiying them - you are just creating an empty array in your sample code.
No I specified the objects I used in the code, I just didnt know that anyone wanted me to paste the whole 177 line script into the forum for what I had hoped would be a simple question, but here it is:
The script has some specific things it looks for in the selected objects, and it's really meant as a way to help me rearrange a bunch of similar low poly objects, in a very specific configuration. I can try manually copying the objects I need into another array without using the slice function, but since it was there I tried using it. It urks me that it doesn't work as I expected, and I'd like to know if I'm using it wrong, or have wrong assumptions, or whatever reason it didn't do what I wanted it to.
The second goal of this script is as a practical bit of code to help me learn Daz Scripting. I know JavaScript very well, and as an interpreted language it's very persnickity. Daz Script seems to share that trait if perhaps not the same set of things it's persnickity about.
As Richard says, how the aGroups array is being populated needs looking at. It has 30 elements, you have selected the first six, and for some reason the element at index 0 is undefined.
As in Javascript, typeof will return 'object' for an array (which is an object). To test for an array, you could use instanceof and/or check the constructor:
Executing Script...
number
Your post of the script code appeared after I posted my earlier response.
Obviously we don't know what your scene looks like, but it seems to me that you have not eliminated all the undefined elements of the array aSelectedNodes before slicing it to chop off the undefined elements at the end, and assigning the result to the array aGroups. When you come to iterate through aGroups, you then hit an undefined element at the beginning.
Clearly, you could just skip over the undefined elements with:
as the first step within your for loop through the elements of aGroups, or strip them all out with the filter() function before the loop. That may nor may not reveal other issues. Alternatively, and without knowing the structure of your scene this isn't clear, work out why some elements of aSelectedNodes are undefined.
It was a blasted +/-1 error. One difference between Daz Script Arrays and JavaScript Arrays I had not yet internalized - in Daz Script they start at 1, and in JavaScript they start at 0.
Changed the nStartNdx of the loop where the error occurs, and the exit check on the loop, an now it works. It was starting at the length ndx, which I think is probably wrong in either case. The exit check allowed the loop to go down to zero (ndx>=0), so that caused a second error.
WIth another fix to use the right incrementing variable to set the height, now it works:
Given groups of four rectangular prisms, it will raise each group 600cm more than the last. Step one complete. Now I need to increase the X and Z scales to gradually make them larger by the same increment.
Arrays start from 0 in DS too.
And for an array of length N, the 'highest' index will be N-1 (ignoring non-numeric, or unordered numeric indexes!). So starting the 'reverse' iteration over aSelectedNodes at aSelectedNodes.length-1 will avoid the attempt to access the undefined element aSelectedNodes[N], which is beyond the end of the array, and thus avoid the original error.
Does Daz script/Javascript/ECMAScript not have a nice, helpful 'Index out of range' error for this type of situation? If not, it really should.
It doesn't, possibly because arrays are not necessarily dimensioned.