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 条评论
登录 后参与评论

相关文章

来自专栏xx_Cc的学习总结专栏

iOS底层原理总结 - 探寻OC对象的本质

3775
来自专栏java初学

hashMap原理(java8)

36317
来自专栏屈定‘s Blog

Java8 Lambda(一)-函数式接口

实习前只是粗略的看了下Java8的一些基本语法,但是没有系统的学习过.在使用一段时间后决定系统的对其进行一次分析,加深对Java8函数式编程的理解,提高自己的编...

2493
来自专栏老马说编程

(54) 剖析Collections - 设计模式 / 计算机程序的思维逻辑

上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类。...

2419
来自专栏chenjx85的技术专栏

leetcode-367-Valid Perfect Square

2424
来自专栏有趣的Python

1-Java面向对象-面向对象

通过前面的学习我们对于java的语法结构有了一定的认识,掌握了分支结构,循环结构等常用的程序逻辑,也能运用这些知识解决一些简单问题。

1401
来自专栏java初学

13.2 具体的集合

2729
来自专栏个人随笔

Java 关于集合框架那点事儿

 1.引入集合框架   采用数组存在的一些缺陷:    1.数组长度固定不变,不能很好地适应元素数量动态变化的情况。    2.可通过数组名.length获取数...

28310
来自专栏杨熹的专栏

【LEETCODE】模拟面试-39. Combination Sum

和subset区别:规定了子集的sum==target 注意,这里传递的起始位置是i,而不是position+1,but why??? helper(res, ...

2745
来自专栏java学习

请问你知道什么是栈吗?

1.1栈的概念及记本操作 栈(stack)又称堆栈,是限制在表的一端进行插入和删除的线性表。其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行...

3058

扫码关注云+社区