Swift中过滤结构体内部数组并保留外层结构体的最优方案问询
保留外层结构体同时过滤内部数组的最优Swift实现
你想要的是保留所有外层events实例,仅对每个实例内部的swimmers_info数组做过滤,只留下符合条件的元素对吧?你的循环写法确实能实现,但我们可以用更简洁、符合Swift函数式编程风格的方式来完成,而且不会修改原数据,更安全。
直接上最优代码
首先先修正一下结构体的命名(Swift规范里类型名首字母要大写,变量名小驼峰,这样代码更易读),然后实现过滤逻辑:
import Foundation // 遵循Swift命名规范调整结构体名称 struct Event { var title: String var unique: Int var swimmersInfo: [SwimInfo] } struct SwimInfo { var name: String var team: String } // 初始化测试数据 let si1 = [ SwimInfo(name:"Smith, John", team:"PHNX"), SwimInfo(name:"Tenay, Teresa", team:"CRIM") ] let si2 = [ SwimInfo(name:"Test, Two", team:"PHNX"), SwimInfo(name:"Female, Swimmer", team:"SSA") ] let eventsArray = [ Event(title: "First Event", unique: 5, swimmersInfo: si1), Event(title: "Second Event", unique: 2, swimmersInfo: si2) ] // 核心过滤逻辑:保留所有外层Event,只过滤内部的swimmersInfo let filteredEvents = eventsArray.map { event in var updatedEvent = event // 因为结构体是值类型,创建副本修改 updatedEvent.swimmersInfo = event.swimmersInfo.filter { $0.team == "SSA" } return updatedEvent } // 验证输出 for event in filteredEvents { print("Event: \(event.title) (ID: \(event.unique))") print("Filtered Swimmers: \(event.swimmersInfo)\n") }
输出结果
Event: First Event (ID: 5) Filtered Swimmers: [] Event: Second Event (ID: 2) Filtered Swimmers: [SwimInfo(name: "Female, Swimmer", team: "SSA")]
为什么这个方案比你的循环更好?
- 不修改原数据:我们创建了新的
Event实例数组,完全不会影响原来的eventsArray,避免了意外修改原数据的风险,这在Swift里是更推荐的Immutable编程方式。 - 代码更简洁清晰:用
map遍历外层数组,结合filter处理内部数组,一行核心逻辑就能搞定,比循环枚举更易读,也更符合Swift的函数式风格。 - 完全匹配需求:所有外层
Event结构体都被保留,每个结构体的swimmersInfo只留下符合条件的元素,完美解决你之前两种尝试的问题。
说说你之前尝试的问题
newarrayEV1用filter:这个方法只会保留包含至少一个符合条件子元素的外层结构体,直接丢失了没有符合条件子元素的First Event,不符合你要保留所有外层结构体的需求。newarrayEV2用map只取过滤后的子数组:这个操作直接丢弃了外层Event的title、unique等所有信息,只剩下过滤后的子数组列表,显然不符合要求。- 循环修改原数组:虽然能实现功能,但代码相对冗长,而且修改了原数据,如果后续还要用到原数组的话就会有问题。
额外扩展:如果想去掉内部数组为空的外层结构体
如果之后你有需求,要过滤掉swimmersInfo为空的Event,只需要在上面的filteredEvents基础上再加一层filter:
let nonEmptyFilteredEvents = filteredEvents.filter { !$0.swimmersInfo.isEmpty }
内容的提问来源于stack exchange,提问作者MW_DEVEL
相关产品推荐
相关产品推荐

