iOS Swift:将数组排序为多维数组
Posted
技术标签:
【中文标题】iOS Swift:将数组排序为多维数组【英文标题】:iOS Swift: Sort array into multidimensional array 【发布时间】:2015-03-01 00:40:04 【问题描述】:我有一个 CKRecords 数组。每条记录都有startTime
和Name
以及其他值。我想做的是首先按唯一的startTime
对记录进行排序,然后在每个 startTime 中按唯一的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)
【问题讨论】:
【参考方案1】:为什么不使用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[$0]!) $0.name < $1.name
println(buildIndex(records))
【讨论】:
你能把g[e.time] = (g[e.time] ?? []) + [e]
写得不那么简洁吗?试图理解那条线。
只是在g
字典中的数组中追加一个元素。
我收到了.map sorted(g[$0]!) $0.name < $1.name
行的Expected type
编译器错误。知道这意味着什么吗?
@colindunnn 我刚刚再次测试了上面的代码,但我看不到那个错误。你修改代码了吗?如果是这样,请告诉我修改后的版本。我也许可以帮助你。
@colindunnn 你的意思是这样的吗? gist.github.com/hisui/f4aea3d1d6f5881eebd2(但是,在这种情况下,buildIndex
的输出必须是 CKRecord
.. 的 3 维数组)【参考方案2】:
首先,您实际上并不是在尝试对数组进行排序,而是在尝试对字典进行排序,该字典不是为按顺序迭代而构建的。事实上,即使你先对数组进行排序,然后像这样构建字典:
var sortedRecords = [NSDate: [String: CKRecord]]()
records.sort return $0.date.timeIntervalSinceDate($1.date) < 0
for record in records
if sortedRecords[record.date] != nil
sortedRecords[record.date] = [String: CKRecord]()
sortedRecords[record.date]![record.name] = record
当您将来对其进行迭代时,无法保证该顺序。也就是说,字典本质上是一个查找表,并且可以在 O(log n) 时间内访问元素。您真正想要做的是要么删除字典,而是使用 [CKRecord]
数组,然后像这样排序:
records.sort $0.date.timeIntervalSinceDate($1.date) == 0 ? $0.name < $1.name : $0.date.timeIntervalSinceDate($1.date) < 0
或者,根据您的最终目标,遍历一系列日期,边走边从字典中提取条目。
【讨论】:
感谢您的解释。我试图在两个地方显示记录。首先作为表格视图(我需要所有记录),然后在详细视图中(我只需要记录的子集)。我对分组的目标是更容易地只访问我需要的信息。但也许有更好的方法。 使用适合特定问题的数据结构。对于 tableView,您需要将记录保存在排序数组中。对于详细视图,构造一个将数组转换为字典并返回它的 getter,例如:lazy var recordsByDate: [NSDate: [String:CKRecord]] ... Dictionary Buildng Method Goes Here ...
【参考方案3】:
您可以执行 CloudKit 查询并确保以正确的排序顺序返回数组,如下所示:
query.sortDescriptors = [NSSortDescriptor(key: "startTime", ascending: true), NSSortDescriptor(key: "Name", ascending: true)]
然后,如果您转到详细视图,您可以使用过滤器来获取当天的记录,如下所示:
var details = records.filter (%0.objectForKey("startTime") As! NSDate) == selectedDate
【讨论】:
以上是关于iOS Swift:将数组排序为多维数组的主要内容,如果未能解决你的问题,请参考以下文章