带开关的通用功能

时间:2018-02-22 23:44:50

标签: swift generics

我正在尝试将数字(#Read data decow <- read.table("decow14ax.freq10.w.tsv", header = TRUE, fill = TRUE) #Converting wordlist in lower case decow$token_lowercase <- tolower(as.character(decow$token...)) #Read word list wordlist <- read.csv("wordlist.csv") #Set frequency counter to 0 wordlist$norm_frequency = 0 #Obtaining frequencies for word list from norm database for (i in 1:nrow(wordlist)) { for (j in 1:nrow(decow_small)) { if (wordlist$word[i]==decow$token_lowercase[j]) { wordlist$norm_frequency[i] <- decow_small$f_raw[j]} } } DoubleFloatCGFloat)转换为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

2 个答案:

答案 0 :(得分:2)

在我使用通用模式之前,我想知道您是否只能使用现有的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 "???"
        }
    }
}

这显然只适用于浮点类型,但这可能足以满足您的需要。如果你想要,正如rmaddy指出的那样,你可以写一个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的方法使得范围变得不那么神秘。

答案 1 :(得分:1)

您也可以尝试使用数字协议。

例如:

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
       }                                                         
    }
}