[Swift] 文字の種類ごとに全角/半角に変換する

とある案件で，入力された文字のうち，数字は半角，カタカナは全角に変換してほしい，というものがありました．

どうせなら，ということで，**数字，英字，カタカナ，その他(記号)ごとに全角/半角を指定**できるような`String`型のExtensionを作りましたので，共有したいと思います．

ぱっと作ったので，もっといい方法があるかもしれません．
もっと簡単にできる方法がありましたら，コメントの方でご教授お願いしますm(._.)m

### 関連部分コード
細かい説明は省きます．

```swift
enum CharacterType {
    case Numeric, English, Katakana, Other
}

func transformFullwidthHalfwidth(transformTypes types :[CharacterType], reverse :Bool=false) -> String {
    var transformedChars :[String] = []
   
    let chars = self.characters.map{ String($0) }
    chars.forEach{
        let halfwidthChar = NSMutableString(string: $0) as CFMutableString
        CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, false)
        let char = halfwidthChar as String
        
        if char.isNumber(transformHalfwidth: true) {
            if let _ = types.filter({$0 == .Numeric}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
        else if char.isEnglish(transformHalfwidth: true) {
            if let _ = types.filter({$0 == .English}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
        else if char.isKatakana() {
            if let _ = types.filter({$0 == .Katakana}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
        else {
            if let _ = types.filter({$0 == .Other}).first {
                CFStringTransform(halfwidthChar, nil, kCFStringTransformFullwidthHalfwidth, reverse)
                transformedChars.append(halfwidthChar as String)
            } else {
                transformedChars.append($0)
            }
        }
    }
    
    var transformedString = ""
    transformedChars.forEach{ transformedString += $0 }
    
    return transformedString
}

func isNumber(transformHalfwidth transform :Bool) -> Bool {
    let halfwidthStr = NSMutableString(string: self) as CFMutableString
    CFStringTransform(halfwidthStr, nil, kCFStringTransformFullwidthHalfwidth, false)
    let str = halfwidthStr as String
 
    return Int(str) != nil ? true : false
}

func isEnglish(transformHalfwidth transform :Bool) -> Bool {
    let halfwidthStr = NSMutableString(string: self) as CFMutableString
    if transform {
        CFStringTransform(halfwidthStr, nil, kCFStringTransformFullwidthHalfwidth, false)
    }
    let str = halfwidthStr as String
    
    let pattern = "[A-z]*"
    do {
        let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
        let result = regex.stringByReplacingMatchesInString(str, options: [], range: NSMakeRange(0, str.characters.count), withTemplate: "")
        if result == "" { return true }
        else { return false }
    }
    catch { return false }
}

func isKatakana() -> Bool {
    let halfwidthStr = NSMutableString(string: self) as CFMutableString
    CFStringTransform(halfwidthStr, nil, kCFStringTransformFullwidthHalfwidth, true)
    let str = halfwidthStr as String
    
    let pattern = "^[\\u30A0-\\u30FF]+$"
    do {           
        let regex = try NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
        let result = regex.stringByReplacingMatchesInString(str, options: [], range: NSMakeRange(0, str.characters.count), withTemplate: "")
        if result == "" { return true }
        else { return false }
    }
    catch { return false }
}
```

### 実行結果
```swift
let str = "aＡこンニﾁﾊ123４５６-+ー＝＋"
print("そのまま            :", str)
print("カタカナ            :", str.transformFullwidthHalfwidth(transformTypes: [.Katakana]))
print("数字               :", str.transformFullwidthHalfwidth(transformTypes: [.Numeric]))
print("英字               :", str.transformFullwidthHalfwidth(transformTypes: [.English]))
print("その他             :", str.transformFullwidthHalfwidth(transformTypes: [.Other]))
print("英数字             :", str.transformFullwidthHalfwidth(transformTypes: [.Numeric, .English]))
print("カタカナ(全角)       :", str.transformFullwidthHalfwidth(transformTypes: [.Katakana], reverse: true))
print(
    "数字半角,カタカナ全角 :",
    str.transformFullwidthHalfwidth(transformTypes: [.Numeric])
        .transformFullwidthHalfwidth(transformTypes: [.Katakana], reverse: true)
)

// 出力 ----------
//そのまま            : aＡこンニﾁﾊ123４５６-+ー＝＋
//カタカナ            : aＡこﾝﾆﾁﾊ123４５６-+ｰ＝＋
//数字               : aＡこンニﾁﾊ123456-+ー＝＋
//英字               : aAこンニﾁﾊ123４５６-+ー＝＋
//その他             : aＡこンニﾁﾊ123４５６-+ー=+
//英数字             : aAこンニﾁﾊ123456-+ー＝＋
//カタカナ(全角)       : aＡこンニチハ123４５６-+ー＝＋
//数字半角,カタカナ全角 : aＡこンニチハ123456-+ー＝＋
```