I don't understand what's happening when I save values via a loop. I initialize an array with default values, then run a loop to assign calculated values to it. In the middle of the loop, I print values, then print values again after the loop is over. The array values sometimes change, even though nothing has been written between print calls (when they change, the values are equal the last value in the array, index 49).
I made a test file which writes four types of values to an array: (1) A new class instance, (2) Calculation, (3) Variable, (4) Hard-code. Saving the same value gives different results between the different write methods:
import Foundation
let numElements : Int = 50
class CustomType{
var x : Double
var y : Double
init(x: Double = 1.23, y: Double = 2.34) {
self.x = x
self.y = y
}
}
// Try this four different ways
var array1 = [CustomType](repeating:CustomType(), count:numElements)
var array2 = [CustomType](repeating:CustomType(), count:numElements)
var array3 = [CustomType](repeating:CustomType(), count:numElements)
var array4 = [CustomType](repeating:CustomType(), count:numElements)
// Checking that defaults were written
print("Pre: Point 1: (\(array1[44].x),\(array1[44].y))")
print("Pre: Point 2: (\(array2[44].x),\(array2[44].y))")
print("Pre: Point 3: (\(array3[44].x),\(array3[44].y))")
print("Pre: Point 4: (\(array4[44].x),\(array4[44].y))")
// --- Fix 1: Problem goes away if I uncomment this:
// array1[44]=CustomType()
// array2[44]=CustomType()
// array3[44]=CustomType()
// array4[44]=CustomType()
// --- Fix 2: Or if you swap these two lines for the following line:
// let index = 44
// do {
for index in 0..<numElements{
let rads = Double(index) * 2 * Double.pi/Double(numElements)
let sinrads = sin(rads), cosrads = cos(rads)
// Four different ways to save to arrays
array1[index] = CustomType(x:sin(rads),y:cos(rads))
array2[index].x = sin(rads)
array2[index].y = cos(rads)
array3[index].x = sinrads
array3[index].y = cosrads
array4[index].x = -0.684547105928689
array4[index].y = 0.7289686274214113
if(index==44){
print("\n== Printing results mid-loop at index 44 ==")
print("During: index: \(index), Calculated Rads: \(rads)")
print("During: Calculated Vals: (\(sin(rads)),\(cos(rads)))")
print("During: Stored 'let' Vals: (\(sinrads),\(cosrads))")
print("During: Point 1: (\(array1[44].x),\(array1[44].y))")
print("During: Point 2: (\(array2[44].x),\(array2[44].y))")
print("During: Point 3: (\(array3[44].x),\(array3[44].y))")
print("During: Point 4: (\(array4[44].x),\(array4[44].y))")
}
}
print("\n== Printing the same results after the loop ==")
print("Post: Point 1: (\(array1[44].x),\(array1[44].y))")
print("Post: Point 2: (\(array2[44].x),\(array2[44].y))")
print("Post: Point 3: (\(array3[44].x),\(array3[44].y))")
print("Post: Point 4: (\(array4[44].x),\(array4[44].y))")
print("\n== Reverse-calculating results from a correct array (array 1) to get the for loop index ==")
print("reverse index calculation 01: \( (atan2(array1[ 1].x,array1[ 1].y) + Double.pi * 0) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 44: \( (atan2(array1[44].x,array1[44].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 45: \( (atan2(array1[45].x,array1[45].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("\n== Reverse-calculating results from an incorrect array (array 2) to get the for loop index ==")
print("reverse index calculation 1: \( (atan2(array2[ 1].x,array2[ 1].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 44: \( (atan2(array2[44].x,array2[44].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
print("reverse index calculation 45: \( (atan2(array2[45].x,array2[45].y) + Double.pi * 2) * Double(numElements)/(2*Double.pi) )")
Which gives the following output:
Pre: Point 1: (1.23,2.34)
Pre: Point 2: (1.23,2.34)
Pre: Point 3: (1.23,2.34)
Pre: Point 4: (1.23,2.34)
== Printing results mid-loop at index 44 ==
During: index: 44, Calculated Rads: 5.529203070318036
During: Calculated Vals: (-0.684547105928689,0.7289686274214113)
During: Stored 'let' Vals: (-0.684547105928689,0.7289686274214113)
During: Point 1: (-0.684547105928689,0.7289686274214113)
During: Point 2: (-0.684547105928689,0.7289686274214113)
During: Point 3: (-0.684547105928689,0.7289686274214113)
During: Point 4: (-0.684547105928689,0.7289686274214113)
== Printing the same results after the loop ==
Post: Point 1: (-0.684547105928689,0.7289686274214113)
Post: Point 2: (-0.12533323356430465,0.9921147013144778)
Post: Point 3: (-0.12533323356430465,0.9921147013144778)
Post: Point 4: (-0.684547105928689,0.7289686274214113)
== Reverse-calculating results from a correct array (array 1) to get the for loop index ==
reverse index calculation 01: 1.0000000000000002
reverse index calculation 44: 43.99999999999999
reverse index calculation 45: 45.0
== Reverse-calculating results from an incorrect array (array 2) to get the for loop index ==
reverse index calculation 1: 49.0
reverse index calculation 44: 49.0
reverse index calculation 45: 49.0
Program ended with exit code: 0
Re-initializing the objects prior to the loop fixes the problem (see "Fix 1" in the comments), but the elements of the array are all initialized during creation and I don't understand why doing it a second time is helpful. The values should all be the same, am I missing something simple?