从其他两个核心数据对象创建复合对象

时间:2014-10-19 10:03:27

标签: ios arrays object core-data swift

我有2个核心数据类。 患者移交。一名患者可以进行多次移交。

Patient.swift

import Foundation
import CoreData

class Patient: NSManagedObject {

    @NSManaged var id: NSNumber
    @NSManaged var firstName: String
    @NSManaged var lastName: String
    @NSManaged var personalNumber: String
    @NSManaged var handovers: NSSet
}

Handover.swift

import Foundation
import CoreData

class Handover: NSManagedObject {

    @NSManaged var date: NSDate
    @NSManaged var status: String
    @NSManaged var time: NSNumber
    @NSManaged var patient: Patient
}

我需要显示在给定日期进行切换的患者列表。它需要按time排序。

以下是我得到的结果集示例。

handovers = db.loadHandovers(NSDate.date())
for handover in handovers {
    let handover = handover as Handover
    println("\(handover.time) - \(handover.patient.firstName) \(handover.patient.lastName)")
}

enter image description here

请注意,患者 Anna Andersson 在8处有4次移交,而8位患者Göte2Andersson 有4次移交。我需要将这些移交给患者分组。但还有另一个问题。如果同一患者在不同时间有更多的移交,则将他们视为一个单独的组。例如,您可以看到 Anna Andersson 在14处进行了另一次移交。这需要是一个单独的组。

+------+-------------------+-------------------+
| TIME |      PATIENT      |  NO. OF HANDOVERS |
+------+-------------------+-------------------+
|      |                   |                   |
| 08   |  Anna Andersson   |  3                |
|      |                   |                   |
| 08   |  Göte 2 Andersson |  4                |
|      |                   |                   |
| 10   |  Göte 2 Andersson |  1                |
|      |                   |                   |
| 11   |  Göte 2 Andersson |  1                |
|      |                   |                   |
| 14   |  Anna Andersson   |  1                |
+------+-------------------+-------------------+

我创建了一个名为CompositeItem的单独类来保存它们。

import Foundation

public class CompositeItem {

    var patient: Patient!
    var handovers: [Handover] = []

    init() {

    }
}

我现在陷入困境的是如何遍历handovers数组并将它们分组并创建复合对象。

我有一个for循环遍历检索到的切换。

private var compositeItems: [CompositeItem] = []

handovers = db.loadHandovers(NSDate.date())

for handover in handovers {
    let handover = handover as Handover

    if compositeItems.isEmpty {
        let item = CompositeItem()
        item.patient = handover.patient
        item.handovers.append(handover)
    } else {
        // How can I check if the current Handover object has the same Patient and the time as the last added Handover.
        // And add it to the last `item`'s handovers array if they do match.
    }
}

我的问题是如何检查当前的切换对象是否具有与上次添加的切换相同的患者和时间。如果它们匹配,则将其添加到最后item的切换数组中。

我真的很感激任何帮助。这部分让我难过。

谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用NSFetchRequest为您进行分组。为此,您必须更改fetch以将其结果作为字典数组(resultType = DictionaryResultType)而不是对象数组返回。然后,您可以指定要按(propertiesToGroupBy)分组的属性,例如。患者姓名和时间,以及您希望包含在结果中的患者(propertiesToFetch),例如。病人姓名,时间,计数。尝试将以下内容插入loadHandovers函数:

public func loadHandovers(date: NSDate) -> [AnyObject] {
    let fetchRequest = NSFetchRequest()
    let entityDescription = NSEntityDescription.entityForName("Handover", inManagedObjectContext: managedObjectContext!)
    let datePredicate = NSPredicate(format: "date > %@ AND date < %@", getStartDate(date), getEndDate(date))
    let descriptor = NSSortDescriptor(key: "time", ascending: true)

    let patientNameExp = NSExpression(forKeyPath:"patient.name")
    let patientNameED = NSExpressionDescription()

    patientNameED.expression = patientNameExp
    patientNameED.name = "patientName"
    patientNameED.expressionResultType = NSAttributeType.StringAttributeType

    let timeED : NSAttributeDescription = entityDescription?.attributesByName["time"] as NSAttributeDescription

    let countExp = NSExpression(format: "count:(name)")
    let countED = NSExpressionDescription()
    countED.name = "count"
    countED.expression = countExp
    countED.expressionResultType = NSAttributeType.Integer32AttributeType

    fetchRequest.resultType = NSFetchRequestResultType.DictionaryResultType
    fetchRequest.propertiesToFetch = [timeED, patientNameED, countED]
    fetchRequest.propertiesToGroupBy = [timeED, patientNameED]

    fetchRequest.entity = entityDescription
    fetchRequest.predicate = datePredicate
    fetchRequest.sortDescriptors = [descriptor]

    var error: NSError?
    let result = managedObjectContext?.executeFetchRequest(fetchRequest, error: &error)
    return result!
}

(为我的Swift语法道歉,这显示我的Playground没有错误,但可能需要选项排序等)。你应该收到一个数组,每个元素都是一个字典。字典将包含“time”,“patientName”和“count”键,您可以使用这些键来填充单元格。

答案 1 :(得分:0)

您可以将复合项目存储在字典而不是数组中。字典键可以是患者对象的NSManagedObjectID,这样您就不会得到多个患者。因此字典可能如下所示:

let patientsWithHandovers = Dictionary<NSManagedObjectID,CompositeItem>()

当您遍历切换时,您可以检查患者是否已经存在于字典中,如果是,则将切换附加到其切换阵列中。

如果患者不在字典中,请创建一个新患者:

patientsWithHandovers[patient.objectID] = CompositeItem(...)

迭代数组并用对象填充字典的示例

let numbers = [1,3,2,4,5,6,11,13,12,15,8,21,22,31]  // array with even and odd numbers
var numberDict = Dictionary<String,[Int]>()  // dictionary for separating evens and odds

// initializing the dictionary
numberDict["even"] = []
numberDict["odd"] = []

for number in numbers {
    if number % 2 == 0 {
        numberDict["even"].append(number)
    }
    else {
        numberDict["odd"].append(number)
    }
}

现在数字在字典中用两个键分隔:甚至奇数

我希望你明白这一点。

答案 2 :(得分:0)

我实际上设法用我试过的旧路线来解决我的问题。以下是我写的代码。

let handovers = db.loadHandovers(NSDate())

for handover in handovers {
    let handover = handover as Handover

    if compositeItems.isEmpty {
        let item = CompositeItem()
        item.patient = handover.patient
        item.handovers.append(handover)

        compositeItems.append(item)
    } else {
        let lastCompositeItem = compositeItems.last!
        let lastHandover = lastCompositeItem.handovers.last!

        if handover.patient.id == lastHandover.patient.id && handover.time == lastHandover.time {
            lastCompositeItem.handovers.append(handover)
        } else {
            let item = CompositeItem()
            item.patient = handover.patient
            item.handovers.append(handover)

            compositeItems.append(item)
        }
    }
}