0

please help me I have following struct and photos attached. I want to find the duplicate drinks and then delete duplicate and change the original drink quantity by adding one

    var id = UUID()
    var name : String
    var price : Double
    var extra : [DrinkExtra]
    var unit : Int
    var date : Date
} 

I have tried following code but producing error and index out of range and no magic happened.

    func mergeItem(){
     
        for i in cartDrinks.indices.sorted(by: { name1, name2 in
            return cartDrinks[name1].name > cartDrinks[name2].name
        }) {
            if cartDrinks[i].name == cartDrinks[i + 1].name {
                cartDrinks[i].unit += 1
                cartDrinks.remove(at: i + 1)
                print("\(cartDrinks[i].name) \(cartDrinks[i].unit)")
            } else {
                print("Nothing found")
            }
        }
        
    }

many thanks in advance enter image description here

Liangn1an
  • 33
  • 6
  • Another approach to consider is to refactor your code so you have one type (say Drink) for the drink itself and one type (say DrinkCounter) that keep track of the units selected for a drink. This way you can leave the Drink objects untouched and only increase/decrease a counter in the DrinkCounter object when the UI changes – Joakim Danielson Nov 07 '21 at 16:16
  • I have requirement string for the drinks, eg two glass of coke, one no ice and another with ice. I want if no requirement then merge together else print separate when goes to the printer. – Liangn1an Nov 07 '21 at 16:36
  • Ok, you can also move the extras to the DrinkCounter then (maybe better name is DrinkOrder) so Drink remains immutable. – Joakim Danielson Nov 07 '21 at 17:01
  • Does this answer your question? [Removing duplicate elements from an array in Swift](https://stackoverflow.com/questions/25738817/removing-duplicate-elements-from-an-array-in-swift) – lorem ipsum Nov 07 '21 at 20:43
  • I managed to find the duplicate value based on the post, however I don't know how to apply it to my own question . my is a struct type. this is the code from other stackoverflow post let crossReference = Dictionary(grouping: cartDrinks) { element in return element.name } let duplicates = crossReference .filter{$1.count > 1 } .flatMap{($0.1)} print(duplicates) – Liangn1an Nov 08 '21 at 01:39

1 Answers1

0

Finally I have following code to complete my desired task. many thanks

    func mergeItem(complete:() -> Void) {
        
        var arr = cartDrinks
        var alacartarr = cartexpress
        arr.enumerated().forEach { index,item in
            if let existIndex = arr.firstIndex(where: {item.name == $0.name }),
               existIndex != index {
                arr[existIndex].unit += arr[index].unit
                arr[index].unit = 0
        }
    }
        arr.removeAll(){$0.unit == 0}
        self.cartDrinks.removeAll()
        self.cartDrinks.append(contentsOf: arr)
        
        alacartarr.enumerated().forEach { index,value in
            if let existedIndex = alacartarr.firstIndex(where: {value.name == $0.name}),
               existedIndex != index {
                alacartarr[existedIndex].quantity += alacartarr[index].quantity
                alacartarr[index].quantity = 0
            }
        }
        alacartarr.removeAll(){$0.quantity == 0}
        cartexpress.removeAll()
        cartexpress.append(contentsOf: alacartarr)
        
        complete()
    }
Liangn1an
  • 33
  • 6