Swift 4中按属性分组数据求助:尝试字典/数组未达理想效果
Swift 4 按属性分组事件数据的实现方案
嘿,我懂你想把这批事件数据按指定属性分组,并且最终得到数组形式结果的需求~之前手动用字典数组折腾没搞定?别慌,Swift 4的标准库其实有现成的方法能帮你轻松实现,我一步步给你讲:
第一步:先定义数据模型(用Codable解析JSON更省心)
直接用字典操作太容易出错,先把JSON映射成Swift结构体,用Codable来自动解析,代码清爽又靠谱:
import Foundation // 单个事件的模型 struct Event: Codable { let name: String let date: String let time: String let am_or_pm: String let day: String let description: String } // 包裹events的顶层模型 struct EventResponse: Codable { let events: [Event] }
第二步:解析你的JSON数据源
把你提供的JSON字符串转换成我们定义的模型数组:
let yourJsonString = """ {"events": [{"name":"event foo","date":"2018-07-21","time":"7:00","am_or_pm":"PM","day":"Saturday","description":"test "}, {"name":"event bar","date":"2018-07-21","time":"7:00","am_or_pm":"PM","day":"Saturday","description":"test2"}, {"name":"event foobar","date":"2018-07-21","time":"11:00","am_or_pm":"PM","day":"Saturday","description":"test3"}]} """ // 把字符串转成Data,用于解析 guard let jsonData = yourJsonString.data(using: .utf8) else { fatalError("无法将JSON字符串转换为Data") } do { // 解析JSON到模型数组 let response = try JSONDecoder().decode(EventResponse.self, from: jsonData) let events = response.events // 这里就是我们要处理的事件数组啦 print("原始事件数组:\(events)") } catch { print("JSON解析失败:\(error.localizedDescription)") }
第三步:按指定属性分组并转成数组形式
Swift 4提供了Dictionary(grouping:by:)方法,能一键把数组按指定key分组,得到[分组key: 对应元素数组]的字典。如果想要数组形式的结果,只需要把字典转成数组即可:
示例1:按time属性分组
// 1. 先按time分组得到字典 let groupedByTime = Dictionary(grouping: events) { $0.time } // 2. 把字典转换成元组数组(每个元素包含分组key和对应事件) let timeGroupArray = groupedByTime.map { (time, eventsInGroup) in (groupKey: time, events: eventsInGroup) } // 打印结果看看 for group in timeGroupArray { print("\n--- 时间:\(group.groupKey) ---") group.events.forEach { print("事件名称:\($0.name)") } }
输出效果会是:
--- 时间:7:00 --- 事件名称:event foo 事件名称:event bar --- 时间:11:00 --- 事件名称:event foobar
示例2:按date属性分组(同理可复用)
如果你想按日期分组,只需要把分组的key换成$0.date就行:
let groupedByDate = Dictionary(grouping: events) { $0.date } let dateGroupArray = groupedByDate.map { (date, eventsInGroup) in (groupKey: date, events: eventsInGroup) }
进阶:用自定义结构体封装分组结果
如果觉得元组不够清晰,可以定义一个专门的分组结构体:
struct EventGroup { let groupKey: String let events: [Event] } // 转换成自定义结构体数组 let dateGroups = groupedByDate.map { EventGroup(groupKey: $0.key, events: $0.value) }
这样后续操作分组数据会更直观,代码可读性也更高~
为啥之前手动用字典数组没搞定?
大概率是手动处理分组逻辑的时候,要自己遍历、判断、添加元素,容易漏情况或者逻辑绕晕。用Swift标准库的grouping方法,底层已经帮你处理好了所有分组逻辑,效率高还不容易出错,再转成数组就是你想要的形式啦!
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

