我在iOS中创建了一个模拟时钟显示器,它也显示了太阳正午和中午之间的区别,所以我需要知道太阳中午的时间才能计算出这个差异。
此api调用:http://api.usno.navy.mil/rstt/oneday?date=today&coords=51.1,-1.0&tz=1
产生以下结果(丢弃一些不相关的字段):
{
"year":2018,
"month":6,
"day":18,
"lon":-1.000000,
"lat":51.100000,
"tz":1,
"sundata":[
{"phen":"BC", "time":"04:02"},
{"phen":"R", "time":"04:49"},
{"phen":"U", "time":"13:05"}, <-- ( Upper Transit/Solar Noon )
{"phen":"S", "time":"21:22"},
{"phen":"EC", "time":"22:09"}]
}
此时我只对太阳中午的当地时间感兴趣(如上例所示“13:05”)并将其转换为中午时间以后的分钟数 - 这对于我的显示目的而言足够准确。
为此,我将数据提取到此Swift结构中:
struct SolarData: Decodable {
let year: Int
let month: Int
let day: Int
let lon: Double
let lat: Double
let tz: Double
let sundata: Array<[String: String]>
/// The number of minutes past clock noon at which solar noon occurs.
public var solarNoonOffset: Int {
let noon = sundata
.filter { $0["phen"] == "U" }
.flatMap { $0 }
.filter { $0.0 == "time" }[0]
.value
let solarNoonHour = Int(noon.prefix(2))
let solarNoonMins = Int(noon.suffix(2))
let offset = (solarNoonHour! - 12) * 60 + solarNoonMins!
return offset
}
}
这有效,但感觉既笨拙又冗长(即使删除了所有错误检查以简化示例),所以我有两个相关的问题:
在结构中,let sundata: Array<[String: String]>
是否与数据有效匹配或过于通用?
可以在多大程度上简化偏移的计算?
答案 0 :(得分:1)
这些方面应该有所作为。基本上,您希望为phen
项目创建课程。您甚至可以使用枚举来提高可读性。
我确信您还可以采取其他措施来提高可读性,例如定义自己的CodingKeys
枚举,为您的网站提供更好的名称,但这取决于您。这应该可以帮到你。
struct SolarData: Decodable {
struct Phenomenon: Decodable {
enum Kind: String, Decodable {
case
beginCivilTwilight = "BC",
rise = "R",
upperTransit = "U",
set = "S",
endCivilTwilight = "EC",
lowerTransit = "L"
}
var phen: Kind
var time: String
}
let year: Int
let month: Int
let day: Int
let lon: Double
let lat: Double
let tz: Double
let sundata: [Phenomenon]
/// The number of minutes past clock noon at which solar noon occurs.
public var solarNoonOffset: Int {
let noon = sundata
.first { $0.phen == .upperTransit }
.map { $0.time }
let solarNoonHour = Int(noon!.prefix(2))
let solarNoonMins = Int(noon!.suffix(2))
let offset = (solarNoonHour! - 12) * 60 + solarNoonMins!
return offset
}
}
let testJson = """
{
"year":2018,
"month":6,
"day":18,
"lon":-1.000000,
"lat":51.100000,
"tz":1,
"sundata":[
{"phen":"BC", "time":"04:02"},
{"phen":"R", "time":"04:49"},
{"phen":"U", "time":"13:05"},
{"phen":"S", "time":"21:22"},
{"phen":"EC", "time":"22:09"}]
}
"""
let solarData = try JSONDecoder().decode(SolarData.self, from: testJson.data(using: .utf8)!)
print("Solar Noon Offset: \(solarData.solarNoonOffset)")