-1

我有以下型号

class Process: Object {
    @objc dynamic var processID:Int = 1
    let steps = List<Step>()
}

class Step: Object {
    @objc private dynamic var stepCode: Int = 0
    @objc dynamic var stepDateUTC: Date? = nil
    var stepType: ProcessStepType {
        get {
            return ProcessStepType(rawValue: stepCode) ?? .created
        }
        set {
            stepCode = newValue.rawValue
        }
    }
}

enum ProcessStepType: Int { // to review - real value
    case created = 0
    case scheduled = 1
    case processing = 2
    case paused = 3
    case finished = 4
}

一个进程可以开始、处理、暂停、恢复(再次处于单步处理中)、暂停、再次恢复等。当前步骤是具有最新 stepDateUTC 的步骤

我正在尝试获取所有进程,最后一步是 stepType 处理“处理”的步骤,即。对于最后一个 stepDate,stepCode 是 2 。我带来了以下谓词......这是行不通的。对执行此类查询的正确执行有任何想法吗?

我最好的试验是那个。是否可以通过一个领域查询获得此结果。

let processes = realm.objects(Process.self).filter(NSPredicate(format: "ANY steps.stepCode = 2 AND NOT (ANY steps.stepCode = 4)")

let ongoingprocesses = processes.filter(){$0.steps.sorted(byKeyPath: "stepDateUTC", ascending: false).first!.stepType == .processing}

我希望会起作用

NSPredicate(format: "steps[LAST].stepCode = \(TicketStepType.processing.rawValue)")

我了解领域不支持 [LAST](根据备忘单)。但是无论如何我可以通过领域查询来实现我的目标吗?

4

1 回答 1

0

有几种方法可以解决这个问题,并且似乎与 date 属性无关,因为列表是按顺序存储的(只要它们没有被更改),因此 List 中的最后一个元素是最后添加的。

第一段代码将过滤最后一个元素是“处理”的进程。我对此进行了长期编码,因此流程更容易理解。

let results = realm.objects(Process.self).filter { p in
    let lastIndex = p.steps.count - 1
    let step = p.steps[lastIndex]
    let type = step.stepType
    if type == .processing {
        return true
    }
    return false
}

请注意,Realm 对象是延迟加载的——这意味着成千上万的对象对内存的影响很小。通过使用 Swift 进行过滤,对象在内存中被过滤,因此影响更加显着。

第二段代码是我建议的,因为它使过滤变得更简单,但需要对 Process 模型进行轻微更改。

class Process: Object {
    @objc dynamic var processID:Int = 1
    let stepHistory = List<Step>() //RENAMED: the history of the steps
    @objc dynamic var name = ""

    //ADDED: new property tracks current step
    @objc dynamic var current_step = ProcessStepType.created.index 
}

我的想法是 Process 模型保留到目前为止已发生的步骤的“历史记录”,然后是 current_step 是什么。

我还修改了 ProcessStepType 枚举,使其更易于过滤。

enum ProcessStepType: Int { // to review - real value
    case created = 0
    case scheduled = 1
    case processing = 2
    case paused = 3
    case finished = 4

    //this is used when filtering
    var index: Int {
        switch self {
        case .created:
            return 0
        case .scheduled:
            return 1
        case .processing:
            return 2
        case .paused:
            return 3
        case .finished:
            return 4
        }
    }
}

然后返回列表中最后一步是“处理”的所有进程,这是过滤器

let results2 = realm.objects(Process.self).filter("current_step == %@", ProcessStepType.processing.index)

最后的想法是在 Process 模型中添加一些代码,这样当一个步骤被添加到列表中时,current_step 变量也会被更新。留给 OP 的编码。

于 2020-03-22T15:03:24.063 回答