iOS Swift:将数组排序为多维数组

iOS Swift: Sort array into multidimensional array

我有一组 CKRecords。每条记录都有 startTime 和一个 Name,以及其他值。我想做的是先按 unique startTime 对记录进行排序,然后在每个 startTime 内按 unique Name.

排序

最终结果将是一个如下所示的数组(我认为):records = [Date: [Name: [CKRecord]]]

这是我现在拥有的:

func buildIndex(records: [CKRecord]) -> [[CKRecord]] {
var dates = [NSDate]()
var result = [[CKRecord]]()

for record in records {
    var date = record.objectForKey("startTime") as! NSDate

    if !contains(dates, date) {
        dates.append(date)
    }
}

for date in dates {
    var recordForDate = [CKRecord]()

    for (index, exercise) in enumerate(exercises) {
        let created = exercise.objectForKey("startTime") as! NSDate

        if date == created {
            let record = exercises[index] as CKRecord
            recordForDate.append(record)
        }
    }
    result.append(recordForDate)
}

return result
}

let records = self.buildIndex(data)

为什么不使用sorted?像这样。

// A simplified version of your `CKRecord` just for demonstration
struct Record {
    let time: NSDate
    let name: String
}

let records = [
    Record(time: NSDate(timeIntervalSince1970: 1), name: "a"),
    Record(time: NSDate(timeIntervalSince1970: 2), name: "b"),
    Record(time: NSDate(timeIntervalSince1970: 1), name: "c"),
    Record(time: NSDate(timeIntervalSince1970: 3), name: "d"),
    Record(time: NSDate(timeIntervalSince1970: 3), name: "e"),
    Record(time: NSDate(timeIntervalSince1970: 2), name: "f"),
]

func buildIndex(records: [Record]) -> [[Record]] {
    var g = [NSDate: [Record]]()
    for e in records {
        if (g[e.time] == nil) {
            g[e.time] = []
        }
        g[e.time]!.append(e) // grouping by `time`
    }
    return sorted(g.keys) { (a: NSDate, b: NSDate) in
        a.compare(b) == .OrderedAscending // sorting the outer array by 'time'
    }
    // sorting the inner arrays by `name`
    .map { sorted(g[[=10=]]!) { [=10=].name < .name } } 
}

println(buildIndex(records))

首先,您并不是真的要在此处对数组进行排序,您是在尝试对字典进行排序,它不是为按顺序迭代而构建的。事实上,即使你先对数组进行排序,然后像这样构建字典:

var sortedRecords = [NSDate: [String: CKRecord]]()
records.sort { return [=10=].date.timeIntervalSinceDate(.date) < 0 }

for record in records {
    if sortedRecords[record.date] != nil {
        sortedRecords[record.date] = [String: CKRecord]()
    }

    sortedRecords[record.date]![record.name] = record
}

以后迭代时无法保证顺序。也就是说,字典本质上是一种查找 table,并且可以在 O(log n) 时间内访问元素。你真正想要做的是要么放弃字典是支持 [CKRecord] 的数组,然后像这样排序:

records.sort { [=11=].date.timeIntervalSinceDate(.date) == 0 ? [=11=].name < .name : [=11=].date.timeIntervalSinceDate(.date) < 0 }

或者,根据您的最终目标,遍历一系列日期,边走边从字典中提取条目。

您可以执行 CloudKit 查询并确保以正确的排序顺序返回数组,如下所示:

    query.sortDescriptors = [NSSortDescriptor(key: "startTime", ascending: true), NSSortDescriptor(key: "Name", ascending: true)]

然后,如果您转到详细信息视图,您可以像这样使用过滤器来获取当天的记录:

   var details = records.filter { (%0.objectForKey("startTime") As! NSDate) == selectedDate }