Swift 什么';删除领域对象的所有未来事件的正确方法是什么?
目前,我正在使用此代码删除所有未来的重复交易:Swift 什么';删除领域对象的所有未来事件的正确方法是什么?,swift,for-loop,realm,crud,Swift,For Loop,Realm,Crud,目前,我正在使用此代码删除所有未来的重复交易: let futureRecurringTransactions = self.transactions.filter(NSPredicate(format: "transactionDescription == %@ && transactionDate >= %@ && transactionCategory == %@", transaction!.transactionDescript
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)
}
}
以下是我的领域数据模型:
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"
}
}
代码是有效的,但我觉得我这样做是业余和笨拙的。有没有更好的方法更准确、更恰当
我认为利用transactionID可能会很好,但每个事务都有一个唯一的transactionID,因此我不确定这将如何工作。我通常要做的是为要放置在集合上的每个约束创建一个唯一的NSPredicate。您可以混合和匹配每个谓词,以形成一组唯一的筛选器。例如:
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),
])
}
}
还要注意的是,您不需要对结果进行循环。您可以删除结果中的所有对象,如下所示:
let realm = try Realm()
try realm.write {
realm.delete(transactions.filter(.futureRepeats(of: transaction)))
}
最后,最好将transactionID作为约束。否则,原始事务将包含在结果中。我通常要做的是为要对集合施加的每个约束创建一个唯一的NSPredicate。您可以混合和匹配每个谓词,以形成一组唯一的筛选器。例如:
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),
])
}
}
还要注意的是,您不需要对结果进行循环。您可以删除结果中的所有对象,如下所示:
let realm = try Realm()
try realm.write {
realm.delete(transactions.filter(.futureRepeats(of: transaction)))
}
最后,最好将transactionID作为约束。否则原始事务将包含在结果中。与其反复运行类似的代码并删除潜在的重复项,为什么不首先防止编写重复项?输入数据时,查询数据以查看是否存在匹配项,如果存在,则阻止写入。这将节省大量cpu周期,并定期重复访问数据库。我不明白,你指的是什么重复项@Jay?我指的是问题中提出的所有未来重复事务重复事务将是“重复”。啊,我指的是每月或每周都会发生的重复交易。不是重复,而是重复的事务。与其反复运行类似的代码并删除潜在的重复,为什么不首先防止编写重复的代码?输入数据时,查询数据以查看是否存在匹配项,如果存在,则阻止写入。这将节省大量cpu周期,并定期重复访问数据库。我不明白,你指的是什么重复项@Jay?我指的是问题中提出的所有未来重复事务重复事务将是“重复”。啊,我指的是每月或每周都会发生的重复交易。不是重复的,而是重复的事务。