Swfit - 阿拉伯数字英文读法

DigitalReadingEN 支持阿拉伯数字转英文读法。
支持 负号、小数点及大小写(支持到万亿,小数点保留4位)
实现原理:

① 判断是否为负数 ②判断是否有小数点 ③如有分别送进不同地方处理
③-1 整数部分 根据英文读法规则,给他们增加逗号,然后根据不同情况处理再拼接起来
③-2 小数部分 相对比较简单,这里取4位有效数字,再进行其他优化处理。
码了一天,终于码出来了。虽然代码有点粗糙,但是还是成型了。改天有空再优化下代码顺便检查下其他BUG。亲们,码字辛苦,来个赞把!(づ ̄3 ̄)づ╭❤~

Swfit - 阿拉伯数字英文读法_第1张图片
DigitalReadingEN

使用方法:

        //使用事例
        let digEn = DigitalReadingEN().digitalDivisionEn(123456789, letter: .small)
        // = one hundred and twenty-three million four hundred and fifty-six thousand seven hundred and eighty-nine point zero one two three
        let digEn2 = DigitalReadingEN().digitalDivisionEn(123.000, letter: .capital)
        // = ONE HUNDRED AND TWENTY-THREE
        let digEnStr = DigitalReadingEN().digitalDivisionEnStr("-1111.112")
       // = minus one thousand one hundred and eleven point one one two

DigitalReadingEN.swift

import Foundation

struct DigitalReadingEN {
    enum Letter {
        case capital,small
    }
    ///① 直接判断数字
    func digitalDivisionEn(num: Double, letter: Letter) -> String {
        if case .small = letter {
           return digitalDivisionEnStr(String(num))
        }
        return digitalDivisionEnStr(String(num)).uppercaseString
    }
    
    ///② 直接判断字符串
    func digitalDivisionEnStr(num: String) -> String {
        // 保证传过来的是数字的字符串
        guard let _ = Double(num) else {
            return "传过来的是什么鬼东西"
        }
        //判断是否有负号
        var newStr = num
        if num.hasPrefix("-") {
            newStr = split(num, splist: "-")[1]
        }
        
        //保证有小数点才执行下面
        guard num.containsString(".") else {
            let positiveNum = integerPart(newStr)
            return !num.hasPrefix("-") ? positiveNum : "minus " + positiveNum
        }
        
        let arrStr = split(newStr, splist: ".")
        let int_num = integerPart(arrStr[0])  //整数部分
        let point_num = decimalPart(arrStr[1]) //小数点部分
        let positiveNum = int_num  + " " + point_num
        return !num.hasPrefix("-") ? positiveNum : "minus " + positiveNum
    }
    
    //给数字加上逗号分隔,方便处理不同读法
    private func addSeparator(num: String) -> String {
        let int_num = num //整数部分
        let rever_numStr = split(String(int_num), splist: "").reverse()
        var index = 0
        var str = ""
        for s in rever_numStr {
            index += 1
            index%3 != 0 ? (str += s) : (str = str + s + ",")
        }
        var numStr = split(str, splist: "")
        if numStr.last == "," { numStr.removeLast() }
        let curr_num = numStr.reverse()
        str = ""
        for s in curr_num { str += s }
        return str
    }
    
    //处理整数部分
    private func integerPart(numStr: String) -> String {
        let numd = addSeparator(numStr)
        let crrStrArr = split(numd, splist: ",")
        var allStr = ""
        switch crrStrArr.count {
        case 1:
            allStr = lastCase(crrStrArr[0], last: .last1)
        case 2:
            let s1 = lastCase(crrStrArr[0], last: .last2)
            let s2 = lastCase(crrStrArr[1], last: .last1)
            allStr = s1 + s2
        case 3:
            let s1 = lastCase(crrStrArr[0], last: .last3)
            let s2 = lastCase(crrStrArr[1], last: .last2)
            let s3 = lastCase(crrStrArr[2], last: .last1)
            allStr = s1 + s2 + s3
        case 4:
            let s1 = lastCase(crrStrArr[0], last: .last4)
            let s2 = lastCase(crrStrArr[1], last: .last3)
            let s3 = lastCase(crrStrArr[2], last: .last2)
            let s4 = lastCase(crrStrArr[3], last: .last1)
            allStr = s1 + s2 + s3  + s4
        case 5:
            let s1 = lastCase(crrStrArr[0], last: .last5)
            let s2 = lastCase(crrStrArr[1], last: .last4)
            let s3 = lastCase(crrStrArr[2], last: .last3)
            let s4 = lastCase(crrStrArr[3], last: .last2)
            let s5 = lastCase(crrStrArr[4], last: .last1)
            allStr = s1 + s2 + s3  + s4 + s5
        default:
            return "太长了,让我喘口气把!"
        }
        return allStr
    }
    
    enum Last12345 {
        case last1, last2, last3, last4, last5
    }
    
    //整数部分的单个模块处理(每个逗号分割为一个模块)
    private func lastCase(numStr: String,last: Last12345) -> String {
        
        var digUnit = ""
        switch last {
        case.last1:
            digUnit = ""
        case .last2:
            digUnit = " thousand "
        case .last3:
            digUnit = " million "
        case .last4:
            digUnit = " billion "
        case .last5:
            digUnit = " trillion "
        }
        
        let currArr = split(numStr, splist: "")
        //处理一位
        if currArr.count == 1 { return dict1[currArr[0]]! + digUnit }
        //处理两位
        if currArr.count == 2 {
            let str2Index = String(Int(currArr[0] + currArr[1])!)
            let str2 = dict1[str2Index]!
            return str2 + digUnit
        }
        
        //确保为三位数时候才进行三位处理
        guard currArr.count == 3 else { return "" }
        /* 处理不同情况 000 00_  _00  ___  0__  */
        if numStr.containsString("000") { return "" }
        if numStr.hasPrefix("00") { return dict1[currArr[2]]! }
        if numStr.hasSuffix("00") {
            return dict1[currArr[0]]! + " hundred" + digUnit
        }
        let str1 = dict1[currArr[0]]!
        let str2Index = String(Int(currArr[1] + currArr[2])!)
        let str2 = dict1[str2Index]!
        var str = str1 + " hundred " + "and " + str2 + digUnit
        if numStr.hasPrefix("0") { str = str2 + digUnit }
        return str
    }
    
   //处理小数部分
   private func decimalPart(deStr: String) -> String {
        let newStr = "0.\(deStr)"
        let str = String(format: "%.4f", Double(newStr)!) //保留4位有效数字
        var readStr = "" //存储读法
        var num = 10
        //优化读法 把 0000 _000 __00 ___0 处理下
        if str.hasSuffix("0000") { return "" }
        if str.hasSuffix("000") {
            num = 1
        } else if str.hasSuffix("00") {
            num = 2
        } else if str.hasSuffix("0") {
            num = 3
        }
        
        let suStr = String(split(str, splist: ".")[1])
        var sIndex = 0
        for s in split(suStr, splist: "") {
            readStr += " " + dict1[s]!
            sIndex += 1
            if sIndex >= num { break }
        }
        return "point" + readStr
    }
    
    //分割字符串
    private func split(selfStr: String, splist: String) -> [String] {
        if splist.isEmpty {
            var strArr = [String]()
            for char in selfStr.characters {
                strArr.append(String(char))
            }
            return strArr //空的话、无缝分割
        }
        return selfStr.componentsSeparatedByString(splist)
    }
    
    //字典对照表
   private let dict1 = ["0":"zero","1":"one","2":"two","3":"three","4":"four","5":"five","6":"six","7":"seven","8":"eight","9":"nine","10":"ten","11":"eleven","12":"twelve","13":"thirteen","14":"fourteen","15":"fifteen","16":"sixteen","17":"seventeen","18":"eighteen","19":"nineteen","20":"twenty","25": "twenty-five", "26": "twenty-six", "24": "twenty-four", "23": "twenty-three", "29": "twenty-nine", "22": "twenty-two", "21": "twenty-one", "27": "twenty-seven", "28": "twenty-eight","30":"thirty","36": "thirty-six", "33": "thirty-three", "39": "thirty-nine", "34": "thirty-four", "38": "thirty-eight", "35": "thirty-five", "31": "thirty-one", "37": "thirty-seven", "32": "thirty-two","40":"forty","42": "forty-two", "41": "forty-one", "46": "forty-six", "49": "forty-nine", "47": "forty-seven", "45": "forty-five", "43": "forty-three", "44": "forty-four", "48": "forty-eight","50":"fifty","56": "fifty-six", "57": "fifty-seven", "52": "fifty-two", "53": "fifty-three", "54": "fifty-four", "58": "fifty-eight", "51": "fifty-one", "59": "fifty-nine", "55": "fifty-five","60":"sixty","65": "sixty-five", "68": "sixty-eight", "64": "sixty-four", "66": "sixty-six", "61": "sixty-one", "63": "sixty-three", "67": "sixty-seven", "62": "sixty-two", "69": "sixty-nine","70":"seventy","78": "seventy-eight", "79": "seventy-nine", "74": "seventy-four", "73": "seventy-three", "75": "seventy-five", "76": "seventy-six", "71": "seventy-one", "72": "seventy-two", "77": "seventy-seven","80":"eighty","84": "eighty-four", "83": "eighty-three", "81": "eighty-one", "85": "eighty-five", "82": "eighty-two", "87": "eighty-seven", "89": "eighty-nine", "86": "eighty-six", "88": "eighty-eight","90":"ninety","93": "ninety-three", "95": "ninety-five", "92": "ninety-two", "97": "ninety-seven", "98": "ninety-eight", "91": "ninety-one", "96": "ninety-six", "99": "ninety-nine", "94": "ninety-four"]
}

你可能感兴趣的:(Swfit - 阿拉伯数字英文读法)