在Swift中Int的前导零

我想将Swift中的Int转换为带有前导零的String。例如,考虑以下代码:

for myInt in 1 ... 3 {
print("\(myInt)")
}

目前的结果是:

1
2
3

但我希望它是:

01
02
03

在Swift标准库中是否有一种干净的方式来做到这一点?

157774 次浏览

假设你想要一个长度为2且前导为0的字段,你可以这样做:

import Foundation


for myInt in 1 ... 3 {
print(String(format: "%02d", myInt))
}

输出:

01
02
03

这需要import Foundation,所以从技术上讲,它不是Swift语言的一部分,而是Foundation框架提供的功能。注意,import UIKitimport Cocoa都包含Foundation,所以如果你已经导入了CocoaUIKit,就没有必要再次导入它。


格式字符串可以指定多个项的格式。例如,如果你试图将3小时,15分钟和7秒格式化为03:15:07,你可以这样做:

let hours = 3
let minutes = 15
let seconds = 7
print(String(format: "%02d:%02d:%02d", hours, minutes, seconds))

输出:

03:15:07

在Swift 5中,你可以选择下面所示的三个例子来解决你的问题。


# 1。使用Stringinit(format:_:)初始化式

Foundation为Swift String提供了一个init(format:_:)初始化式。init(format:_:)有以下声明:

init(format: String, _ arguments: CVarArg...)

返回使用给定格式字符串作为模板初始化的String对象,其余参数值被替换到模板中。

下面的Playground代码展示了如何使用init(format:_:)Int创建一个至少有两个整数数字的String:

import Foundation


let string0 = String(format: "%02d", 0) // returns "00"
let string1 = String(format: "%02d", 1) // returns "01"
let string2 = String(format: "%02d", 10) // returns "10"
let string3 = String(format: "%02d", 100) // returns "100"

# 2。使用Stringinit(format:arguments:)初始化式

Foundation为Swift String提供了一个init(format:arguments:)初始化式。init(format:arguments:)有以下声明:

init(format: String, arguments: [CVarArg])

返回使用给定格式字符串作为模板初始化的String对象,其余参数值根据用户的默认语言环境替换。

下面的Playground代码展示了如何使用init(format:arguments:)Int创建一个至少有两个整数数字的String:

import Foundation


let string0 = String(format: "%02d", arguments: [0]) // returns "00"
let string1 = String(format: "%02d", arguments: [1]) // returns "01"
let string2 = String(format: "%02d", arguments: [10]) // returns "10"
let string3 = String(format: "%02d", arguments: [100]) // returns "100"

# 3。使用NumberFormatter

Foundation提供了NumberFormatter。苹果对此表示:

NSNumberFormatter的实例格式化包含NSNumber对象的单元格的文本表示,并将数值的文本表示转换为NSNumber对象。该表示包括整数、浮点数和双精度浮点数;浮点数和双精度数可以格式化为指定的小数位置。

下面的Playground代码展示了如何创建NumberFormatter,该NumberFormatter从至少有两个整数的Int返回String?:

import Foundation


let formatter = NumberFormatter()
formatter.minimumIntegerDigits = 2


let optionalString0 = formatter.string(from: 0) // returns Optional("00")
let optionalString1 = formatter.string(from: 1) // returns Optional("01")
let optionalString2 = formatter.string(from: 10) // returns Optional("10")
let optionalString3 = formatter.string(from: 100) // returns Optional("100")

与其他使用格式化器的答案不同,你也可以在循环内的每个数字前面添加一个“0”文本,就像这样:

for myInt in 1...3 {
println("0" + "\(myInt)")
}

但是,当您必须为每个单独的数字添加指定数量的0时,formatter通常更好。如果你只需要加一个0,那么它就是你的选择。

对于左填充,添加一个字符串扩展,如下所示:

Swift 5.0 +

extension String {
func PadLeft( totalWidth: Int,byString:String) -> String {
let toPad = totalWidth - self.count
if toPad < 1 {
return self
}
    

return "".padding(toLength: toPad, withPad: byString, startingAt: 0) + self
}
}

使用这种方法:

for myInt in 1...3 {
print("\(myInt)".padLeft(totalWidth: 2, with: "0"))
}

斯威夫特3.0 +

左填充String扩展类似于Foundation中的padding(toLength:withPad:startingAt:)

extension String {
func leftPadding(toLength: Int, withPad: String = " ") -> String {


guard toLength > self.characters.count else { return self }


let padding = String(repeating: withPad, count: toLength - self.characters.count)
return padding + self
}
}

用法:

let s = String(123)
s.leftPadding(toLength: 8, withPad: "0") // "00000123"

在Xcode 8.3.2, iOS 10.3 这是很好的现在

Sample1:

let dayMoveRaw = 5
let dayMove = String(format: "%02d", arguments: [dayMoveRaw])
print(dayMove) // 05

Sample2:

let dayMoveRaw = 55
let dayMove = String(format: "%02d", arguments: [dayMoveRaw])
print(dayMove) // 55

细节

Xcode 9.0.1, swift 4.0

解决方案

数据

import Foundation


let array = [0,1,2,3,4,5,6,7,8]

解决方案1

extension Int {


func getString(prefix: Int) -> String {
return "\(prefix)\(self)"
}


func getString(prefix: String) -> String {
return "\(prefix)\(self)"
}
}


for item in array {
print(item.getString(prefix: 0))
}


for item in array {
print(item.getString(prefix: "0x"))
}

解决方案2

for item in array {
print(String(repeatElement("0", count: 2)) + "\(item)")
}

解决方案3

extension String {


func repeate(count: Int, string: String? = nil) -> String {


if count > 1 {
let repeatedString = string ?? self
return repeatedString + repeate(count: count-1, string: repeatedString)
}
return self
}
}


for item in array {
print("0".repeate(count: 3) + "\(item)")
}

如果您只使用格式字符串处理数字,那么其他答案都很好,但是当您可能有需要填充的字符串时,这个答案也很好(尽管不可否认与所问的问题略有不同,但在精神上似乎是相似的)。此外,如果弦比衬垫长,要小心。

   let str = "a str"
let padAmount = max(10, str.count)
String(repeatElement("-", count: padAmount - str.count)) + str

输出"-----a str"

斯威夫特5

@imanuo answers已经很棒了,但如果你正在使用一个充满数字的应用程序,你可以考虑这样的扩展:

extension String {


init(withInt int: Int, leadingZeros: Int = 2) {
self.init(format: "%0\(leadingZeros)d", int)
}


func leadingZeros(_ zeros: Int) -> String {
if let int = Int(self) {
return String(withInt: int, leadingZeros: zeros)
}
print("Warning: \(self) is not an Int")
return ""
}
    

}

这样你可以在任何地方打电话:

String(withInt: 3)
// prints 03


String(withInt: 23, leadingZeros: 4)
// prints 0023


"42".leadingZeros(2)
// prints 42


"54".leadingZeros(3)
// prints 054

Swift 4*及以上,你也可以试试这个:

func leftPadding(valueString: String, toLength: Int, withPad: String = " ") -> String {
guard toLength > valueString.count else { return valueString }
        

let padding = String(repeating: withPad, count: toLength - valueString.count)
return padding + valueString
}

调用函数:

leftPadding(valueString: "12", toLength: 5, withPad: "0")

< >强输出: “00012“< / p >

使用Swift 5新奇的可扩展插值:

extension DefaultStringInterpolation {
mutating func appendInterpolation(pad value: Int, toWidth width: Int, using paddingCharacter: Character = "0") {
appendInterpolation(String(format: "%\(paddingCharacter)\(width)d", value))
}
}


let pieCount = 3
print("I ate \(pad: pieCount, toWidth: 3, using: "0") pies")  // => `I ate 003 pies`
print("I ate \(pad: 1205, toWidth: 3, using: "0") pies")  // => `I ate 1205 pies`

下面的代码生成了一个前面填充为0的3位字符串:

import Foundation


var randomInt = Int.random(in: 0..<1000)
var str = String(randomInt)
var paddingZero = String(repeating: "0", count: 3 - str.count)


print(str, str.count, paddingZero + str)

输出:

5 1 005
88 2 088
647 3 647