Bug with array variables?

I was working with a pair of arrays today, array1() and array2(), array2 being a copy of array 1.

When looking at my method in the debugger I noticed that array 1 was changing along with array2 when I was making changes to array2.
I’m not sure if this is intended behavior? But it seemed odd to me. Here is some code demonstrating the behavior.

  dim array1() as string = Array( "Baby", "Carrot", "Bike" )
  dim array2() as string
  
  array2() = array1()
  // Both are equal to Array( "Baby", "Carrot", "Bike" ) now
  array2(0) = "Bandit"
  // Now both are equal to Array( "Bandit", "Carrot", "Bike" )
  // array1 should be Array( "Baby", "Carrot", "Bike" ) still?

This isn’t making a ‘copy’, it’s making another reference to the same array. You can think of it like objects: multiple variables can reference the same object and manipulating any variable modifies that object.

In these first two lines you do create 2 arrays, variable array1 references an array with 3 elements and variable array2 references an array with 0 elements.

dim array1() as string = Array( "Baby", "Carrot", "Bike" ) dim array2() as string
In this line the 0 element array referenced by array2 is thrown away. Now both variables reference the same 3 element array.

array2() = array1()

In general, to create an actual copy of arrays you need to loop over all elements and copy them over

[code]dim array1() as string = Array( “Baby”, “Carrot”, “Bike” )
dim array2() as string

for i As integer = 0 to array1.Ubound
array2.Append( array1(i) )
next[/code]

For an array of strings you could get away with tricks something like…

array2 = Split(Join(array1, ","), ",")

But this is horribly inefficient.

Also, instead of writing a loop every time you can wrap it in an extension method. Create a Module (name it whatever you like) and add this method to it, with Global scope.

[code]Function duplicate(extends arr() As STRING) As STRING()

dim last As integer = arr.Ubound

dim r() As STRING
redim r(last)

for i As integer = 0 to last
r(i) = arr(i)
next

return r

End Function[/code]

Now you can copy your arrays like this

array2 = array1.duplicate

For other types of arrays, Integer, Double, etc just add the method to the Module again but replace the 3 occurrences of STRING with Integer, Double, etc.

Making a version with “Object” will work for all object type arrays, Folderitem(), Window(), MyClass(), etc. But it’s not so handy because it only returns an array typed as Object() whereas you typically want FolderItem(), Window(), etc.

To duplicate/copy an object array to a specific object array type you need to pass that specific array type to the method instead of returning a generic Object one.

[code]Sub duplicateInto(extends arr() As Object, dest() As Object)

if dest = nil then return

dim last As integer = arr.Ubound

redim dest(last)

for i As integer = 0 to last
dest(i) = arr(i)
next

End Sub[/code]

and so it’s used a little differently

[code]dim objs1() As PushButton = Array(PushButton1, PushButton2, PushButton3)
dim objs2() As PushButton

objs1.duplicateInto( objs2 )[/code]

Note that one of the differences is the destination array has to be dimmed before the duplication call. With String arrays it can be done on the same line.

dim array2() As String = array1.duplicate

Thanks Will, I figured this was probably the case. Thank you for putting so much detail into your answer.