Swift中Int的前导零


305

我想将IntSwift中的a 转换为String前导零的a。例如,考虑以下代码:

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

当前的结果是:

1
2
3

但我希望它是:

01
02
03

Swift标准库中是否有一种干净的方法可以做到这一点?

Answers:


670

假设您希望字段长度为2,且前导零为零,则可以这样做:

import Foundation

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

输出:

01
02
03

这需要import Foundation因此从技术上讲不是斯威夫特语言的一部分,而是由提供的功能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

2
尽管这不是Swift的一部分,但实际上看起来很干净。我认为还没有Swift本机的方法,所以这可能是目前最接近的方法。谢谢,vacawama。:)
Jeehut 2014年

1
顺便说一句:如果我只想在数字前加一个零,那么我会选择println("0\(myInt)")您的建议。那将使用Swift本机String类,而不是通过NSString格式化。
Jeehut 2014年

6
直到您到达“ 10”为止都是有用的,嘿
Jose M Pan

7
String(format: "%03d", myInt)会给你的"000", "001", ... , "099", "100"
vacawama

1
如果-3, -9出现类似value的值,就会出现这些问题,它仍然返回相同的值而没有前导零。
Codetard

139

使用Swift 5,您可以选择以下三个示例之一来解决您的问题。


#1 使用Stringinit(format:_:)初始值设定项

Foundation提供Swift Stringinit(format:_:)初始化程序。init(format:_:)具有以下声明:

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

返回一个String对象,该对象使用给定的格式字符串作为模板进行初始化,其余参数值将替换为该对象。

以下Playground代码显示了如何使用来创建一个至少具有两个整数的String格式化格式:Intinit(format:_:)

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 Stringinit(format:arguments:)初始化程序。init(format:arguments:)具有以下声明:

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

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

以下Playground代码显示了如何使用来创建一个至少具有两个整数的String格式化格式:Intinit(format:arguments:)

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

基金会提供NumberFormatter。苹果对此表示:

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

以下Playground代码显示了如何创建从至少NumberFormatter返回两个整数的a:String?Int

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")

我想当您想在多个位置以相同方式设置数字格式时,您的答案是正确的。因为我没有要求,所以我选择了vacawama的答案是正确的,但是。但是,谢谢您的回答!:)
Jeehut 2014年

@ImanouPetit。仅供参考,我使用的是最少3位数字。如果我没有明确打开包装,即让formattedNumber = formatter.stringFromNumber(counter)!然后字符串包含Optional(“ 001”),因此我动态选择图像路径的代码失败。用'!'展开解决了问题
codecowboy15年

11

对于左填充,请添加如下字符串扩展名:

迅捷2.0 +

extension String {
    func padLeft (totalWidth: Int, with: String) -> String {
        let toPad = totalWidth - self.characters.count
        if toPad < 1 { return self }
        return "".stringByPaddingToLength(toPad, withString: with, startingAtIndex: 0) + self
    }
}

雨燕3.0 +

extension String {
    func padLeft (totalWidth: Int, with: String) -> String {
        let toPad = totalWidth - self.characters.count
        if toPad < 1 { return self }
        return "".padding(toLength: toPad, withPad: with, startingAt: 0) + self
    }
}

使用此方法:

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

1
为什么?!这有什么好处?
Mike Glukhov

7

迅捷3.0+

左填充String扩展名类似于padding(toLength:withPad:startingAt:)inFoundation

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"

1
如果withPad传递的参数超过单个字符,这可能会或可能不会按用户期望的那样工作。
nhgrif

4

斯威夫特5

@imanuo的答案已经很不错了,但是如果您使用的是数量众多的应用程序,则可以考虑使用以下扩展名:

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

扩展FTW .. !! 这在Swift 4中也能正常工作。对于那些努力将旧代码从3迁移到4,并最终迁移到Swift 5的人来说,... :)
Nick N

3

在Xcode 8.3.2,iOS 10.3中,到目前为止还算不错

样本1:

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

示例2:

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

1

如果仅使用格式字符串处理数字,则其他答案很好,但是当您可能需要填充字符串时,这是很好的方法(尽管公认的问题与所提问题略有出入,但在本质上似乎相似)。另外,请注意弦线是否比打击垫长。

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

输出量 "-----a str"


0

细节

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)")
}

就像您的repeatElement方法一样,请参阅我关于填充字符串的答案。
–'possen

这些将不适用于两位数的整数(例如10变为010)。同样,最初的问题专门询问有关标准库的解决方案。@ImanouPetit的上述答案是首选。
cleverbit

-12

与使用格式化程序的其他答案不同,您还可以在循环内的每个数字前面添加“ 0”文本,如下所示:

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

但是,当必须为每个单独的数字添加指定数量的0时,格式化程序通常会更好。但是,如果您只需要加一个0,那么实际上这只是您的选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.