【问题标题】:Can I create a predicate based on the properties of child class objects?我可以根据子类对象的属性创建谓词吗?
【发布时间】:2019-01-24 05:37:59
【问题描述】:

我有两个类:Activity 和 Action。 Activity是父类,Action是子类,这是一对多的关系。在设置 NSFetchedResultsController 时,我想根据子类的属性设置谓词。这是一个例子......

fetchRequest.predicate = NSPredicate(format: "filter only activities that have actions which have their date property equalling today")

如果我要使用 for in 循环过滤活动,这就是它的样子......

for activity in activities
{
    if activity.actions != nil
    {
        for action in activity.actions
        {
            if action.date == today
            {
                // add activity to filtered array
            }
        }
    }
}

【问题讨论】:

    标签: swift core-data nspredicate nsfetchedresultscontroller


    【解决方案1】:

    您可以在NSPredicate 中使用SUBQUERY。这里我使用了NSArray 作为演示。

    let today = Date()
    
    let array: NSArray = [
        Activity(actions: [
            Action(date: today)
            ]),
        Activity(actions: [
            Action(date: Date(timeIntervalSince1970: 0))
            ])
    ]
    
    // here is your predicate
    let result = array.filtered(using: NSPredicate(format: "SUBQUERY(actions, $action, $action.date == %@) .@count > 0", today as CVarArg))
    print(result.count) // 1
    

    请注意,我在这里使用== 来比较日期,这意味着只有当日期完全 等于today 时才会匹配。如果“今天”是指“24 小时内的任何时间”,那么您将不得不使用this question 中建议的答案:

    func getLastAndNextMidnight(date: Date) -> (Date, Date) {
        let dateComponents = Calendar.current.dateComponents([.year, .month, .day], from: date)
        var oneDay = DateComponents()
        oneDay.day = 1
        let lastMidnight = Calendar.current.date(from: dateComponents)!
        let nextMidnight = Calendar.current.date(byAdding: oneDay, to: lastMidnight)!
        return (lastMidnight, nextMidnight)
    }
    let midnights = getLastAndNextMidnight(date: today)
    let result = array.filtered(using: NSPredicate(format: "SUBQUERY(actions, $action, ($action.date >= %@) AND ($action.date <= %@)) .@count > 0", midnights.0 as CVarArg, midnights.1 as CVarArg))
    print(result.count)
    

    【讨论】:

      【解决方案2】:

      今天有什么动作吗?谓词格式:

      "ANY actions.date == today"
      

      【讨论】:

      • 我相信这适用于上面的示例。但是,如果我需要验证多个属性,我将不得不使用子查询。该解决方案似乎更灵活。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      • 2019-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      相关资源
      最近更新 更多