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 }
我有一组 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 }