iOS-数字转为人名币大写(Swift4.0)

在iOS中,对数字的格式化操作,我第一个想到的就是它NumberFormatter,所以我写了下面这个函数

extension String {
    func numberRMM() -> String {
        guard let num = Double(self) else {
            return ""
        }
        let format = NumberFormatter()
        format.locale = Locale(identifier: "zh_CN")
        format.numberStyle = .spellOut
        format.minimumIntegerDigits = 1
        format.minimumFractionDigits = 0
        format.maximumFractionDigits = 2
        return format.string(from: NSNumber(value: num)) ?? ""
    }
}

经测试后

// 输入
print(1234566.05.numberRMM())
// 打印结果 一百二十三万四千五百六十六点〇五

这显然不是我们要的结果,不过我们还是可以利用这个结果,再加上字符串替换,来实现我们的需求 首先全部字符串的替换如下函数

let formattedString = text.replacingOccurrences(of: "一", with: "壹")
                          .replacingOccurrences(of: "二", with: "贰")
                          .replacingOccurrences(of: "三", with: "叁")
                          .replacingOccurrences(of: "四", with: "肆")
                          .replacingOccurrences(of: "五", with: "伍")
                          .replacingOccurrences(of: "六", with: "陆")
                          .replacingOccurrences(of: "七", with: "柒")
                          .replacingOccurrences(of: "八", with: "捌")
                          .replacingOccurrences(of: "九", with: "玖")
                          .replacingOccurrences(of: "十", with: "拾")
                          .replacingOccurrences(of: "百", with: "佰")
                          .replacingOccurrences(of: "千", with: "仟")
                          .replacingOccurrences(of: "〇", with: "零")

之后我们再对这个字符串进行处理

  1. 先判断是否是整数,如果是整数,则在后面加上元整两个字就是我们要的结果了,代码如下 // 整数处理 let texts = formattedString.components(separatedBy: "点") if sept.count > 0 && isInt { return texts[0].appending("元整") }
  2. 如果是小数,此时无论有多少位小数,我们都需要保留两位小数,即角和分,后面的数字直接丢弃掉(实际业务中也不会出现有2位小数以上的数),处理方法如下 // 小数处理 let decStr = sept[1] intStr = intStr.appending("元").appending("\(decStr.first!)角") if decStr.count > 1 { intStr = intStr.appending("\(decStr[decStr.index(decStr.startIndex, offsetBy: 1)])分") } else { intStr = intStr.appending("零分") } return intStr

经过处理后再次测试如下

print(666.005.numberRMM()) // 陆佰陆拾陆元整
print(666.00.numberRMM())  // 陆佰陆拾陆元整
print(666.05.numberRMM())  // 陆佰陆拾陆元零角伍分
print(666.10.numberRMM())  // 陆佰陆拾陆元壹角零分
print(666.1.numberRMM())   // 陆佰陆拾陆元壹角零分
print(666.numberRMM())     // 陆佰陆拾陆元整

最后再贴一下完整的代码

extension Double {
    func numberRMM() -> String {
        return String(self).numberRMM()
    }
}
extension String {
    /// 人名币大写
    func numberRMM() -> String {
        guard let num = Double(self) else {
            return ""
        }
        let format = NumberFormatter()
        format.locale = Locale(identifier: "zh_CN")
        format.numberStyle = .spellOut
        format.minimumIntegerDigits = 1
        format.minimumFractionDigits = 0
        format.maximumFractionDigits = 2
        let text = format.string(from: NSNumber(value: num)) ?? ""
        let sept = self.components(separatedBy: ".")
        let decimals: Double? = sept.count == 2 ? Double("0." + sept.last!) : nil
        return self.formatRMM(text: text, isInt: decimals == nil || decimals! < 0.01)
    }

    private func formatRMM(text: String, isInt: Bool) -> String {
        let formattedString = text.replacingOccurrences(of: "一", with: "壹")
                                  .replacingOccurrences(of: "二", with: "贰")
                                  .replacingOccurrences(of: "三", with: "叁")
                                  .replacingOccurrences(of: "四", with: "肆")
                                  .replacingOccurrences(of: "五", with: "伍")
                                  .replacingOccurrences(of: "六", with: "陆")
                                  .replacingOccurrences(of: "七", with: "柒")
                                  .replacingOccurrences(of: "八", with: "捌")
                                  .replacingOccurrences(of: "九", with: "玖")
                                  .replacingOccurrences(of: "十", with: "拾")
                                  .replacingOccurrences(of: "百", with: "佰")
                                  .replacingOccurrences(of: "千", with: "仟")
                                  .replacingOccurrences(of: "〇", with: "零")
        let sept = formattedString.components(separatedBy: "点")
        var intStr = sept[0]
        if sept.count > 0 && isInt {
            // 整数处理
            return intStr.appending("元整")
        } else {
            // 小数处理
            let decStr = sept[1]
            intStr = intStr.appending("元").appending("\(decStr.first!)角")
            if decStr.count > 1 {
                intStr = intStr.appending("\(decStr[decStr.index(decStr.startIndex, offsetBy: 1)])分")
            } else {
                intStr = intStr.appending("零分")
            }
            return intStr
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

聊聊HystrixThreadPool

hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java

761
来自专栏跟着阿笨一起玩NET

c# 使用timer定时器操作,上次定时到了以后,下次还未执行完怎么处理

------解决方案-------------------------------------------------------- 开始的时候,禁用定时器,你...

2621
来自专栏一个会写诗的程序员的博客

java.base.jmod

/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods$ jmod list java....

1112
来自专栏码匠的流水账

spring security reactive获取security context

本文主要研究下reactive模式下的spring security context的获取。

1752
来自专栏前端儿

Web 前端颜色值--字体--使用,整理整理

颜色值 CSS 颜色使用组合了红绿蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义。对光源进行设置的最低值可以是 0(十六进制 00)。最高值是 2...

2232
来自专栏SpringBoot

java串口错误,no rxtxSerial in java.library.path

1.在jre/bin下添加rxtxParallel.dll,rxtxSerial.dll 文件

952
来自专栏我和未来有约会

简练的视图模型 ViewModel

patterns & practices Developer Center 发布了 Unity Application Block 1.2 for Silver...

2169
来自专栏余生开发

echarts太阳分布图-饼图来回穿梭

var dom = document.getElementById("container");

1152
来自专栏WOLFRAM

向日葵中的数学之美

1823
来自专栏MelonTeam专栏

Bitmap 源码阅读笔记

导语: Android 系统上的图片的处理,跟Bitmap 这个类脱不了关系,我们有必要去深入阅读里面的源码,以便在工作中能更好的处理Bitmap相关的问题...

2478

扫码关注云+社区