Iterating over array changes values of a different var


Sorry for perhaps noob question. However, I would expect the values of ~list remain unchanged yet they change along with ~list1. And it seems to be the case only for .do. Is there any solution to this or do I need to assign the original values to the ~list once again after I execute the function ?

~list = [[1,0,1],[1,3,1],[1,2,3]]
~list1 = ~list
~list1 ={ arg lists,i;{arg item, i; if(item == 1, {lists.put(i,1)}, {lists.put(i,0)}) }) });

this works just fine

~list = [[1,0,1],[1,3,1],[1,2,3]]
~list1 = ~list.scramble

Thank you !

You need ~list1 = ~list.deepCopy.

That’s not a correct expectation.

Both variables are references to the same list object.

If you want list1 to be a different object that starts with the same contents, that requires copying the original object.


1 Like

Oh I see !
Thank you for such swift response!

… and the reason your second example works is that scramble returns a new collection

so it’s sort of doing the .copy for you

(i take the time to note this because it’s kind of cool but also non-obvious which methods manipulate the receiver and which return a copy,

e.g. .sort vs. .scramble

and the famous .add, which really sounds like it’s adding, but usually actually returns a copy with the added thing



out now!

1 Like

Not exactly. For List, Set, Dictionary, etc, it adds to the same object and returns the same object.

For arrays, it will return the same object unless it’s already used up all of its slots, and then it will return a new one. Because you can’t be 100% sure of sticking with the same object, you have to assume the worst and always write array = array.add(x);.