删除 Realm 对象所有未来出现的正确方法是什么? [英] What's the correct way to delete all future occurrences of a Realm object?

查看:60
本文介绍了删除 Realm 对象所有未来出现的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在使用此代码删除所有未来的重复交易:

Currently, I am using this code to delete all future repeat transactions:

let futureRecurringTransactions = self.transactions.filter(NSPredicate(format: "transactionDescription == %@ && transactionDate >= %@ && transactionCategory == %@", transaction!.transactionDescription!, transaction!.transactionDate as CVarArg, transaction!.transactionCategory!))
            
            for transaction in futureRecurringTransactions {
                try! self.realm.write {
                    self.realm.delete(transaction)
                }
            }

这是我的 Realm 数据模型:

Here is my Realm data model:

import RealmSwift

class Transaction: Object {
    
    @objc dynamic var transactionDescription: String? = nil
    @objc dynamic var transactionAmount = 0.0
    @objc dynamic var transactionDate = Date()
    @objc dynamic var transactionCategory: Category? = nil
    @objc dynamic var repeatInterval = ""
    @objc dynamic var isCleared = false
    @objc dynamic var transactionName = ""
    @objc dynamic var transactionID = UUID().uuidString
    
    convenience init(theDate: Date) {
        self.init()
        self.transactionDate = theDate
    }
    
    override static func primaryKey() -> String? {
        return "transactionID"
    }
        
}

代码有效,但感觉我的做法是业余的和笨拙的.有没有更准确、更合适的更好的方法?

The code works, but it feels like the way I'm doing it is amateur and clunky. Is there a better way that is more accurate and proper?

我认为使用 transactionID 可能会很好,但每个交易都有一个唯一的 transactionID,所以我不确定它是如何工作的.

I thought it might be good to utilize the transactionID , but each transaction has a unique transactionID, so I'm not sure how that would work.

推荐答案

我通常做的是为要放置在集合上的每个约束创建一个唯一的 NSPredicate.您可以混合和匹配每个谓词以形成一组独特的过滤器.例如:

What I typically do is create a unique NSPredicate for each constraint you want to place on the collection. You can mix and match each predicate to form a unique set of filters. For example:

extension NSPredicate {
    static func transactionDescriptionEqualTo(_ description: String?) -> NSPredicate {
        if let description = description {
            return .init(format: "transactionDescription == %@", description)
        }
        return .init(format: "transactionDescription == nil")
    }

    static func transactionCategoryEqualTo(_ category: Category?) -> NSPredicate {
        if let category = category {
            return .init(format: "transactionCategory == %@", category)
        }
        return .init(format: "transactionCategory == nil")
    }

    static func transactionDateIsAfter(_ date: Date) -> NSPredicate {
        return .init(format: "transactionDate >= %@", date as NSDate)
    }

    static func transactionIDNotEqualTo(_ id: String) -> NSPredicate {
        return .init(format: "transactionID != %@", id)
    }

    static func futureRepeats(of transaction: Transaction) -> NSPredicate {
        return NSCompoundPredicate(andPredicateWithSubpredicates: [
            .transactionDescriptionEqualTo(transaction.transactionDescription),
            .transactionCategoryEqualTo(transaction.transactionCategory),
            .transactionDateIsAfter(transaction.transactionDate),
            .transactionIDNotEqualTo(transaction.transactionID),
        ])
    }
}

另请注意,您不需要遍历结果.您可以像这样删除结果中的所有对象:

Also note that you don't need to loop over the results. You can delete all objects in the results like this:

let realm = try Realm()
try realm.write {
    realm.delete(transactions.filter(.futureRepeats(of: transaction)))
}

最后,将 transactionID 作为约束包含在内是一个好主意.否则原始交易将包含在结果中.

Lastly, it's a good idea to include the transactionID as a constraint. Otherwise the original transaction will be included in the results.

这篇关于删除 Realm 对象所有未来出现的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆