Swfit - 阿拉伯数字英文读法

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

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

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"]
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容