swift - 如何获取嵌套结构中的所有属性名称
问题描述
假设我有以下结构:
struct Location: Codable, Loopable {
var altitude: Double?
var coordinate: Coordinate?
struct Coordinate: Codable, Loopable {
var latitude: Double?
var longitude: Double?
}
var course: Double?
var courseAccuracy: Double?
var floor: Floor?
struct Floor: Codable, Loopable {
var level: Int?
}
var horizontalAccuracy: Double?
var speed: Double?
var speedAccuracy: Double?
var timestamp: Timestamp?
struct Timestamp: Codable, Loopable {
var year: Int?
var month: Int?
var day: Int?
var hour: Int?
var minute: Int?
var second: Int?
}
var verticalAccuracy: Double?
var deviceName: String?
var validPosition: Bool?
}
现在我想为结构实现两种方法。一个应该返回名称中包含所有父级的所有属性名称,另一个应该返回这些属性的所有值。
第一种方法的结果应该如下所示(我们将其命名为 allProperties()):
["altitude", "coordinate.latitude", "coordinate.longitude", "course", "courseAccuracy", "floor.level", "horzontalAccuracy", "speed", "speedAccuracy", "timeststamp.year", "timestamp.month", "timestamp.day", "timeststamp.hour", "timestamp.minute", "timestamp.second", "verticalAccuracy", "deviceName", "validPosition"]
第二种方法的结果(我们将其命名为 allValues())应该如下所示:
[500.0, 48.000000, 10.00000, 120.0, 5.0, 4, 5.0, 3.0, 1.0, 2021, 07, 25, 22, 43, 50, 10.0, "iPhone", true]
如您所见,我的示例结构与其他结构嵌套。在我的真实项目中,结构有两个以上的嵌套“级别”。属性类型也不是唯一的。在最底层,它们都是基本数据类型(Double、Bool、String、Int)。
我试图从这个线程修改解析嵌套结构的解决方案,这似乎是一个优雅的解决方案:How to loop over struct properties in Swift?
现在我的问题:
- 属性名称的方法只给出一个带有“some”的数组。
- 但是属性值的方法返回正确的数组
["some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some"]
到目前为止,这是我的协议代码:
protocol Loopable {
func allProperties(limit: Int) -> [String]
func allValues(limit: Int) -> [Any]
}
extension Loopable {
func allProperties(limit: Int = Int.max) -> [String] {
return props(obj: self, count: 0, limit: limit)
}
func allValues(limit: Int = Int.max) -> [Any] {
return values(obj: self, count: 0, limit: limit)
}
private func props(obj: Any, count: Int, limit: Int) -> [String] {
let mirror = Mirror(reflecting: obj)
var result: [String] = []
for (prop, val) in mirror.children {
guard let prop = prop else { continue }
if limit == count {
result.append(prop)
} else {
let subResult = props(obj: val, count: count + 1, limit: limit)
subResult.count == 0 ? result.append(prop) : result.append(contentsOf: subResult)
}
}
return result
}
private func values(obj: Any, count: Int, limit: Int) -> [Any] {
let mirror = Mirror(reflecting: obj)
var result: [Any] = []
for (_, val) in mirror.children {
//guard let val = val else { continue } // This line does not compile
if limit == count {
result.append(val)
} else {
let subResult = values(obj: val, count: count + 1, limit: limit)
subResult.count == 0 ? result.append(val) : result.append(contentsOf: subResult)
}
}
return result
}
}
我在这里做错了什么?为什么属性标签总是“一些”?
解决方案
推荐阅读
- java - 如何使用不同的系统属性值执行两个完全相同的 Maven 配置文件?
- c - 为什么会出现分段错误?
- angular - 如何在角度 html 模板中动态更改 Ionic 元素的属性?
- javascript - 根据字典长度创建多个图表
- node.js - 使用 Axios Node.js 请求 oAuth2 令牌 - 使用“请求”但不适用于 Axios
- awk - 将每一列除以另一列
- firebase - 在 Flutter 中从 Firebase RealTime DB 接收对象
- wpf - 当应用程序不在焦点时更改键盘语言
- python - 为什么程序不循环?
- find - 在 find 命令中查找不支持 printf 的 AIX 系统上的前 N 个最旧文件