我正在尝试将数字(Double、Float、CGFloat、Int32)转换为String。
protocol DirectionStringConvertible {
var direction: String { get }
}
extension Double: DirectionStringConvertible {
var direction: String {
switch self {
case 0...11.24: return "N"
case 11.25...33.74: return "NNE"
...
default: return ""
}
}
}
extension CGFloat: DirectionStringConvertible { var direction: String { return Double(self).direction } }
extension Float: DirectionStringConvertible { var direction: String { return Double(self).direction } }
extension Int32: DirectionStringConvertible { var direction: String { return Double(self).direction } }所以我可以像下面这样使用:
CGFloat(12).direction
Double(190).direction但是,我想知道使用泛型类型的更好方法。有点像
extension String {
static func direction<T>(_ value: T) -> String {
switch value {
case 0...11.24: return "N"
case 11.25...33.74: return "NNE"
...
default: return ""
}
}
}发布于 2018-02-23 00:31:32
在讨论泛型模式之前,我想知道您是否可以只使用现有的FloatingPoint协议,因为所有浮点类型都已经符合该协议:
extension FloatingPoint {
var direction: String {
let value = ((self - 32 / 360) * 16 / 360).rounded()
switch value {
case 0: return "N"
case 1: return "NNE"
case 2: return "NE"
case 3: return "ENE"
case 4: return "E"
case 5: return "ESE"
case 6: return "SE"
case 7: return "SSE"
case 8: return "S"
case 9: return "SSW"
case 10: return "SW"
case 11: return "WSW"
case 12: return "W"
case 13: return "WNW"
case 14: return "NW"
case 15: return "NNW"
case 16: return "N"
default: return "???"
}
}
}这显然只适用于浮点类型,但也许这对您的目的来说已经足够了。如果您想要,正如罗曼底所指出的,您可以编写一个BinaryInteger扩展,该扩展将整数类型转换为浮点类型,然后它可以使用上面的内容:
extension BinaryInteger {
var direction: String {
return Double(Int(self)).direction
}
}或者您可以执行一个Numeric扩展,其中它们是Comparable,乘以某些因子,使阈值为整数:
extension Numeric where Self: Comparable {
var direction: String {
switch self * 4 {
case 0 ..< 45: return "N"
case 45 ..< 135: return "NNE"
case 135 ..< 225: return "NE"
case 225 ..< 315: return "ENE"
case 315 ..< 405: return "E"
case 405 ..< 495: return "ESE"
case 495 ..< 585: return "SE"
case 585 ..< 675: return "SSE"
case 675 ..< 765: return "S"
case 765 ..< 855: return "SSW"
case 855 ..< 945: return "SW"
case 945 ..< 1035: return "WSW"
case 1035 ..< 1125: return "W"
case 1125 ..< 1215: return "WNW"
case 1215 ..< 1305: return "NW"
case 1305 ..< 1395: return "NNW"
case 1395 ... 1440: return "N"
default: return "???"
}
}
}或者阿兰的方法,乘以100,使范围不那么神秘。
发布于 2018-02-23 02:47:12
您也可以尝试使用数字协议。
例如:
func direction<T:Numeric>(_ a:T)-> String where T:Comparable
{
let dirNames = ["NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","N"]
.reduce([(1125 as T,"N")]){ $0 + [($0.last!.0+2250,$1)]}
return a < 0 ? direction(a + 360) : dirNames.first{ a * 100 < $0.0}?.1 ?? direction(a - 360)
}通过使用整数比较值(2位精度乘以100 ),该函数将适用于整数参数,而不必定义两组单独的值。
使用扩展名和switch语句,它可以如下所示:
extension Numeric where Self:Comparable
{
var direction:String
{
switch self * 100
{
case 0..<1125 : return "N"
case 1125..<3375 : return "NNE"
case 3375..<5625 : return "NE"
// ...
case 33750..<36000 : return "N"
case _ where self < 0 : return (self + 360).direction
default : return (self - 360).direction
}
}
}https://stackoverflow.com/questions/48939051
复制相似问题