DigitalReadingEN 支持阿拉伯数字转英文读法。
支持 负号、小数点及大小写(支持到万亿,小数点保留4位)
实现原理:
① 判断是否为负数 ②判断是否有小数点 ③如有分别送进不同地方处理
③-1 整数部分 根据英文读法规则,给他们增加逗号,然后根据不同情况处理再拼接起来
③-2 小数部分 相对比较简单,这里取4位有效数字,再进行其他优化处理。
码了一天,终于码出来了。虽然代码有点粗糙,但是还是成型了。改天有空再优化下代码顺便检查下其他BUG。亲们,码字辛苦,来个赞把!(づ ̄3 ̄)づ╭❤~
使用方法:
//使用事例
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"]
}