You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:42:50