RomanNumeralKit

CocoaPods Version Languages Platform

Build Status codecov

为 Swift 提供一流的罗马数字支持。

入乡随俗,像罗马人一样编码。

简介

要有效使用此框架,需要了解罗马数字是什么。背景信息可以在维基百科上找到。

特性

局限性

固定的数值范围

我们理解的标准罗马数字仅限于 1 到 3,999 的值。没有 0 的概念。现代学者已经提出了扩展数字系统以支持大于 3,999 的值的方案,但我们不认可任何这些扩展,并谴责提议者为异端。

大多数程序不会处理高于 3,999 的数字,而且世界在公历 3,999 年之后也不复存在,所以没有必要担心。

iPhone 型号名称

RomanNumeralKit 不支持与最新的 iPhone 型号名称(如“Xs”)之间的转换。

要求

安装

CocoaPods

将 RomanNumeralKit 添加到您的 Podfile

pod 'RomanNumeralKit', '~> 1.0.0`

请访问 CocoaPods 网站以获取有关 CocoaPods 的一般用法和安装说明。

Swift Package Manager

将 RomanNumeralKit 添加到您的 Package.swiftdependencies 值中

dependencies: [
    .package(url: "https://github.com/kylehughes/RomanNumeralKit.git", from: "1.0.0")
]

用法

在您要使用的 Swift 文件的顶部导入 RomanNumeralKit

import RomanNumeralKit

常量

为从 1 到 3,999 的所有有效罗马数字提供常量。除非您正在进行从其他类型的转换,否则您永远不需要使用初始化器。

所有常量都可以通过使用它们的大写 Unicode 字符直接访问。

print(MMCDIX)           // Prints "MMCDIX"
print(MMCDIX.symbols)   // Prints "[M, M, C, D, I, X]"

XCTAssertEqual(MMCDIX, RomanNumeral(.M, .M, .C, .D, .I, .X))    // True

转换

我们提供便捷的机制来将 RomanNumeral 转换为常用类型以及从常用类型转换而来。

应该注意的是,这些是真正的转换:RomanNumeral 实例的后备值是记号组。我们不持有 Int 引用,因为这不符合框架的精神。

构造器

提供构造器以将 IntString 转换为 RomanNumeral

print(RomanNumeral(from: 2409))     // Prints "MMCDIX"
print(RomanNumeral(from: "MMCDIX")) // Prints "MMCDIX"

当可以推断出 RomanNumeral 类型时,我们还支持从 IntString 字面量的转换。

let numeralFromInt: RomanNumeral = 2409
let numeralFromString: RomanNumeral = "MMCDIX"

print(numeralFromInt)       // Prints "MMCDIX"
print(numeralFromString)    // Prints "MMCDIX"

属性

提供实例级属性以将 RomanNumeral 转换为 IntString 值。

print(MMCDIX.intValue)      // Prints "2409"
print(MMCDIX.stringValue)   // Prints "MMCDIX"

我们还提供各种 *Convertible 协议,以允许类型返回它们自身的不同 RomanNumeralRomanNumeralSymbol 表示形式。

算术运算

由于我们符合 Numeric 协议,因此支持(并且需要)加法、减法和乘法运算。我们使用的算法允许我们直接操作罗马数字符号,而不是进行与 Int 之间的转换。

XCTAssertEqual(MD + CMIX, MMCDIX)   // True
XCTAssertEqual(MMM - DXCI, MMCDIX)  // True
XCTAssertEqual(XI * CCXIX, MMCDIX)  // True

性能

我们对真实性的承诺确实会产生影响。

下表比较了在新的 MacBook Pro 上,Int 算术运算与罗马数字算术运算的性能。

运算 (100x) Int 罗马数字 慢 %
加法 0.00000127秒 0.151秒 11,889,663.78%
减法 0.00000151秒 0.0761秒 5,992,025.98%
乘法 0.00000204秒 0.0575秒 4,527,459.06%

应该注意的是,这比任何古代罗马人进行算术运算都要快得多。谁能对进步提出异议呢?

版权文本

我们提供的最有用的功能是版权文本的自动格式化。

print(MDCCLXXVI.copyrightText)  // Prints "Copyright © MDCCLXXVI"

加法记数法

此框架的默认记数法是减法记数法 - 这就是 RomanNumeral 实例所表示的。我们提供 AdditiveRomanNumeral 结构体,用于使用加法记数法初始化数字。我们还支持两种记数法之间的转换。

两种记数法都实现了 RomanNumeralProtocol 协议,并支持相同的通用接口。

let additiveNumeral = AdditiveNotation(.M, .M, .C, .C, .C, .C, .V, .I, .I, .I, .I)

print(additiveNumeral)              // Prints "MMCCCCVIIII"
print(additiveNumeral.intValue)     // Prints "2409"

XCTAssertEqual(additiveRomanNumeral.romanNumeral, MMCDIX)           // True
XCTAssertEqual(MMCDIX.additiveRomanNumeral, additiveRomanNumeral)   // True

扩展

我们为现有的 Swift 类型提供了各种扩展,以使常见的操作更容易。

Calendar & DateComponent 扩展

Calendar 对象及其生成的 DateComponents 能够将年份转换为 RomanNumeral

if let currentYear = Calendar.current.currentYearAsRomanNumeral {
    print(currentYear)                  // Prints "MMXIX"
    print(currentYear.intValue)         // Prints "2019"
    print(currentYear.copyrightText)    // Prints "Copyright © MMXIX"
}

if let americasBirthYear = Calendar.current.yearAsRomanNumeral(fromDate: americasBirthDate) {
    print(americasBirthYear)                // Prints "MDCCLXXVI"
    print(americasBirthYear.intValue)       // Prints "1776"
    print(americasBirthYear.copyrightText)  // Prints "Copyright © MDCCLXXVI"
}

Int & String 扩展

我们将 IntString 遵循 *RomanNumeralConvertible 协议,以使用这些基础类型完成衔尾蛇。

print(2409.romanNumeral)                    // Prints "MMCDIX"
print(2409.additiveRomanNumeral)            // Prints "MMCCCCVIIII"
print("MMCDIX".romanNumeral)                // Prints "MMCDIX"
print("MMCCCCVIIII".additiveRomanNumeral)   // Prints "MMCCCCVIIII"

作者

Kyle Hughes

my twitter

贡献

RomanNumeralKit 目前不接受源代码贡献。

许可证

RomanNumeralKit 在 MIT 许可证下可用。