0

I wrote a model like this as an exercise :

struct Store {
    var name : String
    var bills : Array<Bill>
    var category : Category?
}

struct Bill {
    var date : String
    var amount : Float
}

struct Category {
    var name : String
    var tags : Array<String>
}

and when I'm searching if a store already exist to add a bill to it instead of creating a new store, my code doesn't work. It acts like if the result of the search is a copy of the Array element . I would like to have a reference.

var stores : Array <Store> = Array()
for billStatment in billStatements! {
    let billParts = billStatment.split(separator: ",")
    if billParts.count > 0 {
        let bill : Bill = Bill(date:String(billParts[0]), amount: Float(billParts[2])!)
        var store : Store = Store(name:String(billParts[1]), bills: [bill], category: nil)


        if var alreadyAddedStore = stores.first(where: {$0.name == String(billParts[1])}) {
            alreadyAddedStore.bills.append(bill)
            print("yeah found it \(alreadyAddedStore)") // the debugger breaks here so I know the "first" method is working. If I print alreadyAddedStore here I have one more element, that's fine.
        } else {
            stores.append(store)
        }

    }
}

 print("\(stores.count)") // If I break here for a given store that should contains multiple elements, I will see only the first one added in the else statement.

Can anyone tell me what I am doing wrong?

Serverless chap
  • 183
  • 1
  • 9
jerome
  • 51
  • 6

1 Answers1

0

As already noted, you're confusing value (struct) semantics with reference (class) semantics.

One simple fix would be the change stores to a dictionary with the name as your key:

var stores : Dictionary<String, Store> = [:]

and use it like this:

if(stores[store.name] == nil) {
    stores[store.name] = store
}
else {
    stores[storeName].bills.append(bill)
}
GetSwifty
  • 7,568
  • 1
  • 29
  • 46