Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Featurescript: passing by reference.

jrs_spedleyjrs_spedley Member Posts: 71 ✭✭
I keep getting stung by passing by reference.

I have a multi dimension array which I am recursively parsing but the only way I can get it to work is if every item is in a box.

e.g as a trivial example ...
var x=new box([new box(1), new box(2), new box( [new box(3), new box(4)] ) ]);
output(x);
clear(x);
output(x);
    
function clear(x is box) {
    for (var y in x[]) {
        if (y[] is array)
            clear(y);
        else
            y[]=0;
    }
}

function output(x is box) {
    for (var y in x[]) {
        if (y[] is array)
            output(y);
        else
            print(y[]);
    }
}

I did try returning the array to the same variable in the hope that it would replace it but that doesn't work either ...
var x=[1, 2, [3, 4] ];
x=clear(x);
print(x);
    
function clear(x) {
    for (var y in x) {
        if (y is array)
            y=clear(y);
        else
            y=0;
    }
    return x;
}

Am I missing something or is the only way to do it like the first example?

Comments

  • konstantin_shiriazdanovkonstantin_shiriazdanov Member Posts: 1,221 ✭✭✭✭✭
    arrays are "immutable" you should create a copy of array
    function clear(x) {
    var xCleared = [];
        for (var y in x) {
            if (y is array)
                xCleared = append(xCleared, clear(y));
            else
                xCleared = append(xCleared, 0);<br>    }
        return xCleared;<br>}
  • ilya_baranilya_baran Onshape Employees, Developers, HDM Posts: 1,212
    Konstantin's solution is also the right thing to do from a performance point of view (append is actually faster than modifying an array via x[i] = blah;)
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • jrs_spedleyjrs_spedley Member Posts: 71 ✭✭
    Ah, that explains a lot.  My structure isn't changing, just the values so I can pass the arrays by value and put the values in boxes. Not perfect but I can manage with that.  Thanks.
    var x=[new box(1), new box(2),  [new box(3), new box(4)]  ];
    clear(x);
    output(x);
        
    function clear(x is array) {
        for (var y in x) {
            if (y is array)
                clear(y);
            else
                y[]=0;
        }
    }
    
    function output(x is array) { for (var y in x) { if (y is array) output(y); else print(y[]); } }



  • konstantin_shiriazdanovkonstantin_shiriazdanov Member Posts: 1,221 ✭✭✭✭✭
    I can't really understand why you had to wrap everything in boxes? are you trying to implement something like "set" datastructure?
  • jrs_spedleyjrs_spedley Member Posts: 71 ✭✭
    edited April 2019
    I have a many parts within parts and their positions and sizes are not determined until the whole structure has been processed, hence changing the data in a recursive fashion and the use of boxes to achieve this.
    I use a first pass to calculate minimum sizes and number of parts in each subpart and then a second pass using the dimensions from the first pass to create the parts.

    I would have used a different method if I'd have known passing by reference was such a problem when I started! :)
  • konstantin_shiriazdanovkonstantin_shiriazdanov Member Posts: 1,221 ✭✭✭✭✭
    edited April 2019
    then you could also try to change array item by iterator:
    function clear(x) {
        for (i=0; i < size(x); i+=1) {
            if (x[i] is array)
                x[i] = clear(x[i]);
            else
                x[i] = 0;<br>    }
        return x;<br>}
  • jrs_spedleyjrs_spedley Member Posts: 71 ✭✭
    Yes, I was trying iterating but kept crashing onShape (it would fail to update the part studio and logging out and back in would log me in twice).

    I though it was a problem with featurescript as I couldn't see any errors but I'll try again, making a mistake is easy when you try and change code to function differently.
  • konstantin_shiriazdanovkonstantin_shiriazdanov Member Posts: 1,221 ✭✭✭✭✭
    I use a first pass to calculate minimum sizes and number of parts in each subpart and then a second pass using the dimensions from the first pass to create the parts.
    For case like that i would propose to make associated data structures - iterate through original array and add array items to the map structure with the fields which contain the item itself, and item "metadata". On the new passes you can add more associated data keeping it all in one place
Sign In or Register to comment.