Swift Array Append Overwriting Other Array Values

Swift Array Append Overwriting Other Array Values

Your objectTemplates array stores references to two GameObject instances that were created in initializeObjectTemplates. When your timer fires you select one of these 'template' objects, modify it and add it to the array. However, the array is merely storing references to the objects you add to it, and you only have two objects, even though you are adding those objects to the array multiple times.

When you call populateObjectTemplate you modify one of the two object templates, which means that all other entries in the array that refer to that particular template will reflect those modifications. You need populateObjectTemplate to return a new GameObject, using the information in the template;

func populateObjectTemplate(obj: GameObject, step: Int) -> GameObject {

let newGameObject=GameObject(passed_x: 0,
passed_y: obj.passed_y,
passed_max: obj.passed_max,
passed_min: obj.passed_min,
passed_points: obj.passed_points,
passed_img: obj.passed_img,
passedLengthOfTimeOnScreen: obj.passedLengthOfTimeOnScreen,
passedBottomChance: obj.passedBottomChance,
passedTopChance: obj.passedTopChance,
passedId: obj.passedId)

let widthBoundary = Float(self.view.frame.width - 20)
let heightBoundary = Float(self.view.frame.height - 20)

let placex = CGFloat(Random.within(20.0...widthBoundary))
newGameObject.x = placex

let placey = CGFloat(Random.within(50.0...heightBoundary))
newGameObject.y = placey

newGameObject.expiration = obj.lengthOfTimeOnScreen + step
newGameObject.id = step

newGameObject.button = populateObjectButton(obj)

return newGameObject
}

Swift Append() method overwrite previous data]

RequestItem is reference type and you are using always the (reference to the) same item.

Create a new instance inside the loop

var requestItems: [RequestItem] = []

func setUpData() {
for i in 1...10 {
if i < 3 {
let requestItem = RequestItem()
requestItem.itemId = i as NSNumber
requestItem.requestedQty = 10
requestItem.name = "Item name \(i)"

self.requestItems.append(requestItem)

print("--------------------------------------------Start--------------------------------------------")
print( requestItems )
print("--------------------------------------------End--------------------------------------------")
}
}
}

Adding to swift array keeps overwriting last object

You're appending to a copy of the global array, but don't appear to ever set that updated array back, so the global array is not changing.

Assuming you want keep the global data saved whenever you append to it, I would recommend designing your Globals struct to take care of this automatically:

struct Globals {

// Convenience variable for the standard defaults
private static var Defaults: NSUserDefaults { return NSUserDefaults.standardUserDefaults() }

struct SavedCalculationData {
private static let DataArrayKey = "savedDataArray"
static var dataArray: [String] {
get {
return Defaults.objectForKey(DataArrayKey) as? [String] ?? []
}
set {
// This setter is called when the array contents change,
// not just when a new array is set
Defaults.setObject(newValue, forKey: DataArrayKey)
Defaults.synchronize()
}
}
}
}

Then you can update the global data more succinctly:

Globals.SavedCalculationData.dataArray.append(copyText)

new element is Array overwrites previous member swift

Your app is navigating from ViewController->classPickViewController->ViewController, so you have a new instance of ViewController which will start with a new empty array.

You should look into unwind segues so that you can move back to the presenting ViewController.

You also need to use something like Core Data to persist your data between executions of your app.

I would store an array of a "Contact" struct rather than having two arrays

The last element in my array overwrite all previous elements

You always append same skill to the array. And each time you modifying it in for loop. You should create new Skill every time.

for skill_item in stu_data {
let skills = Skill()
...
}

Your approach would work if Skill was a value type (struct), but it is a reference type (class) and pointing to the same object.

Simple way to replace an item in an array if it exists, append it if it doesn't

Given your use case, in which you're always checking $0.<prop> == newthing.<prop>, you can lift this a little more by adding:

mutating func replaceOrAppend<Value>(_ item: Element, 
firstMatchingKeyPath keyPath: KeyPath<Element, Value>)
where Value: Equatable
{
let itemValue = item[keyPath: keyPath]
replaceOrAppend(item, whereFirstIndex: { $0[keyPath: keyPath] == itemValue })
}

You can then use it like:

struct Student {
let id: Int
let name: String
}

let alice0 = Student(id: 0, name: "alice")
let alice1 = Student(id: 1, name: "alice")
let bob = Student(id: 0, name: "bob")

var array = [alice0]

array.replaceOrAppend(alice1, firstMatchingKeyPath: \.name) // [alice1]
array.replaceOrAppend(bob, firstMatchingKeyPath: \.name) // [alice1, bob]

And of course if you do this a lot, you can keep lifting and lifting.

protocol Identifiable {
var id: Int { get }
}

extension Student: Identifiable {}

extension Array where Element: Identifiable {
mutating func replaceOrAppendFirstMatchingID(_ item: Element)
{
replaceOrAppend(item, firstMatchingKeyPath: \.id)
}
}

array.replaceOrAppendFirstMatchingID(alice0) // [alice1, alice0]


Related Topics



Leave a reply



Submit