0

I am attempting to remove duplicate elements of my Transaction object. The Transactions are being loaded from Firestore and displayed onto a UTableView. I tried to follow this answer [here][1] however I got an error that budgetData is not hashable. Is there a way I can remove duplicate Transactions that have the same "transId" and return an updated array of budgetdata?

  var budgetData: [Transaction] = []

func loadCatTransactions(){
    if let catId = self.categoryId{
        guard let user = Auth.auth().currentUser?.uid else { return }
        print("userFromLoadChat::\(user)")
        db.collection("users").document(user).collection("Transactions")
            .whereField("catId", isEqualTo: catId)
            .getDocuments() {
                snapshot, error in
                if let error = error {
                    print("\(error.localizedDescription)")
                } else {
                    self.budgetData.removeAll()
                    for document in snapshot!.documents {
                        let data = document.data()
                        let title = data["name"] as? String ?? ""
                        let date = data["date"] as? String ?? ""
                        let amount = data["amount"] as? Double ?? 0
                        let id = data["transId"] as? String ?? ""

                        let trans = Transaction(catId:catId,title: title, dateInfo: date, image: UIImage.groceriesIcon, amount: amount)
                        self.budgetData.append(trans)
                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    }
                }
            }
    }
}
func uniq<S : Sequence, T : Hashable>(source: S) -> [T] where S.Iterator.Element == T {
    var buffer = [T]()
    var added = Set<T>()
    for elem in source {
        if !added.contains(elem) {
            buffer.append(elem)
            added.insert(elem)
        }
    }
    return buffer
}


  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
 
    return self.budgetData.count
}

struct Transaction {
var catId : String? = nil
var title: String
var dateInfo: String
var image: UIImage
var amount: Double
var annualPercentageRate: Double?
var trailingSubText: String?
var uid: String?
var outOfString: String?
var category: String?
var dictionary:[String:Any]{
    return [
        "title": title,
        "dateInfo":dateInfo,
        "amount":amount,
        "annualPercentageRate":annualPercentageRate,
        "trailingSubText":trailingSubText,
        "uid": uid,
        "outOfString": outOfString,
        "category": category
    ]
}

} [1]: Removing duplicate elements from an array in Swift

2
  • Can you show the code for your Transaction model? Commented Feb 25, 2021 at 23:51
  • At a high level, I would think that loading your results into a Dictionary with transId as the key and the Transaction as the value would give you a dictionary containing a unique list of Transactions. Commented Feb 25, 2021 at 23:58

1 Answer 1

0

You need to make Transaction object Hashable. Try this

struct Transaction{
     var transId: String
}
extension Transaction: Hashable{
     static func ==(lhs: Transaction, rhs: Transaction) -> Bool {
        return lhs.transId == rhs.transId
     }
 }


var budgetData = [Transaction(transId: "a"), Transaction(transId:"c"), 
                  Transaction(transId: "a"), Transaction(transId: "d")]
var tranSet = Set<Transaction>()
budgetData = budgetData.filter { (transaction) -> Bool in

   if !tranSet.contains(transaction){
      tranSet.insert(transaction)
      return true
    }
    return false
}
Sign up to request clarification or add additional context in comments.

1 Comment

Set insert method returns a property called inserted exactly for this purpose. Btw you can use RangeReplaceableCollection mutating method removeAll(where:). Check this post ==> budgetData.removeAll{!set.insert($0).inserted}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.