SwiftのIntの先行ゼロ


305

IntSwift のin Stringを先行ゼロ付きのa に変換したいのですが。たとえば、次のコードを考えてみます。

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

現在の結果は次のとおりです。

1
2
3

しかし、私はそれがなりたいです:

01
02
03

Swift標準ライブラリ内でこれを行うきれいな方法はありますか?

回答:


670

先行ゼロのあるフィールド長2が必要だとすると、次のようになります。

import Foundation

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

出力:

01
02
03

これにはimport Foundation、技術的にはSwift言語の一部ではなく、Foundationフレームワークによって提供される機能が必要です。両方のことを注意import UIKitしてはimport 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ネイティブの方法はないので、今のところこれが最も近いかもしれません。バカワマさん、ありがとうございます。:)
Jeehut 2014

1
ちなみに、私が自分の番号の前に1つのゼロが欲しいだけなら、私はprintln("0\(myInt)")あなたの提案を選びました。NSStringのフォーマットを行う代わりに、SwiftネイティブのStringクラスを使用します。
Jeehut 2014

6
「10」に到達するまでは便利です、へへ
ホセMパン

7
String(format: "%03d", myInt)あなたに与えるでしょう"000", "001", ... , "099", "100"
vacawama

1
のような値が-3, -9発生した場合のこれらの問題は、先行ゼロなしで同じ値を返します。
Codetard 2018

139

Swift 5では、問題を解決するために、以下に示す3つの例のいずれかを選択できます。


#1。Stringinit(format:_:)初期化子を使用する

FoundationSwift Stringinit(format:_:)イニシャライザを提供します。init(format:_:)次の宣言があります:

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

String残りの引数値が代入されるテンプレートとして、指定されたフォーマット文字列を使用して初期化されたオブジェクトを返します。

次のPlaygroundコードは、を使用StringIntて、少なくとも2桁の整数でフォーマットされたを作成する方法を示していますinit(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:)初期化子を使用する

FoundationSwift Stringinit(format:arguments:)イニシャライザを提供します。init(format:arguments:)次の宣言があります:

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

String与えられたフォーマット文字列をテンプレートとして使用して初期化されたオブジェクトを返します。テンプレートには、ユーザーのデフォルトロケールに従って残りの引数値が代入されます。

次のPlaygroundコードは、を使用StringIntて、少なくとも2桁の整数でフォーマットされたを作成する方法を示していますinit(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。表現には、整数、浮動小数点数、倍精度浮動小数点数が含まれます。floatおよびdoubleは、指定された小数点位置にフォーマットできます。

次のPlaygroundコードは、少なくとも2桁の整数でからNumberFormatter返さ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")

複数の場所で同じように数値をフォーマットする場合は、正しい答えだと思います。私はそれを求めなかったので、正解としてヴァカワマの答えを選びました。でも答えてくれてありがとう!:)
Jeehut 2014

@ImanouPetit。参考までに、これを最小桁数3で使用しました。明示的にアンラップしない場合、つまり、formattedNumber = formatter.stringFromNumber(counter)とします。次に、文字列にはOptional( "001")が含まれているため、イメージパスを動的に選択するコードは失敗します。「!」でアンラップすると問題が解決します
codecowboy

11

左パディングの場合は、次のような文字列拡張を追加します。

Swift 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
    }
}

Swift 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

Swift 3.0以降

左パディングStringと同様の拡張padding(toLength:withPad:startingAt:)Foundation

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渡された引数が1文字以上の場合にユーザーが期待するとおりに機能する場合と機能しない場合があります。
nhgrif 2017

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アプローチのように、文字列をパディングするための私の答えを見てください。
18年

これらは2桁の整数では機能しません(たとえば、10は010になります)。また、元の質問では、標準ライブラリに関連するソリューションを具体的に求めていました。@ImanouPetitによる上記の回答が推奨されます。
18

-12

フォーマッターを使用する他の回答とは異なり、次のように、ループ内の各数値の前に「0」テキストを追加することもできます。

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

しかし、フォーマッタは、別々の数値ごとに指定された量の0を追加する必要がある場合に、多くの場合より優れています。ただし、0を1つ追加するだけでよい場合は、それは実際の選択肢です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.