Führende Nullen für Int in Swift


305

Ich möchte ein Intin Swift in ein Stringmit führenden Nullen konvertieren . Betrachten Sie zum Beispiel diesen Code:

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

Derzeit ist das Ergebnis:

1
2
3

Aber ich möchte, dass es so ist:

01
02
03

Gibt es eine saubere Möglichkeit, dies in den Swift-Standardbibliotheken zu tun?

Antworten:


670

Angenommen, Sie möchten eine Feldlänge von 2 mit führenden Nullen, dann tun Sie Folgendes:

import Foundation

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

Ausgabe:

01
02
03

Dies erfordert import Foundationtechnisch gesehen, dass es nicht Teil der Swift-Sprache ist, sondern eine vom FoundationFramework bereitgestellte Funktion . Beachten Sie, dass beide import UIKitund import Cocoainclude Foundationnicht erneut importiert werden müssen, wenn Sie bereits Cocoaoder importiert haben UIKit.


Die Formatzeichenfolge kann das Format mehrerer Elemente angeben. Wenn Sie beispielsweise versuchen, 3Stunden, 15Minuten und 7Sekunden zu formatieren , können 03:15:07Sie dies folgendermaßen tun:

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

Ausgabe:

03:15:07

2
Obwohl dies nicht Teil von Swift ist, sieht es tatsächlich sehr sauber aus. Ich denke, es gibt einfach keine Swift-native Methode, also könnte dies vorerst die nächste sein. Danke, Vacawama. :)
Jeehut

1
Übrigens: Wenn ich nur eine einzige Null vor meiner Nummer haben wollte, würde ich println("0\(myInt)")Ihren Vorschlag vorziehen. Das würde die native Swift-String-Klasse verwenden, anstatt die NSString-Formatierung zu durchlaufen.
Jeehut

6
Ist nützlich, bis Sie "10" erreichen, hehe
Jose M Pan

7
String(format: "%03d", myInt)werde dir geben "000", "001", ... , "099", "100".
Vacawama

1
Dies ist ein Problem, wenn ein Wert wie -3, -9auftritt. Es wird immer noch dasselbe ohne eine führende Null zurückgegeben.
Codetard

139

Mit Swift 5 können Sie eines der drei unten gezeigten Beispiele auswählen , um Ihr Problem zu lösen.


# 1. Verwenden Stringdes init(format:_:)Initialisierers

Foundationbietet Swift Stringeinen init(format:_:)Initialisierer. init(format:_:)hat die folgende Erklärung:

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

Gibt ein StringObjekt zurück, das mithilfe einer bestimmten Formatzeichenfolge als Vorlage initialisiert wurde, in die die verbleibenden Argumentwerte eingesetzt werden.

Der folgende Spielplatzcode zeigt, wie Sie ein StringFormat Intmit mindestens zwei ganzzahligen Ziffern erstellen, indem Sie Folgendes verwenden 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. Verwenden Stringdes init(format:arguments:)Initialisierers

Foundationbietet Swift Stringeinen init(format:arguments:)Initialisierer. init(format:arguments:)hat die folgende Erklärung:

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

Gibt ein StringObjekt zurück, das mithilfe einer bestimmten Formatzeichenfolge als Vorlage initialisiert wurde, in die die verbleibenden Argumentwerte gemäß dem Standardgebietsschema des Benutzers eingesetzt werden.

Der folgende Spielplatzcode zeigt, wie Sie ein StringFormat Intmit mindestens zwei ganzzahligen Ziffern erstellen, indem Sie Folgendes verwenden 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. Verwenden vonNumberFormatter

Stiftung bietet NumberFormatter. Apple sagt dazu:

Instanzen NSNumberFormatterFormat der Textdarstellung von Zellen , die enthalten NSNumberObjekte und konvertieren Textdarstellungen numerischer Werte in NSNumberObjekten. Die Darstellung umfasst Ganzzahlen, Floats und Doubles. Floats und Doubles können auf eine bestimmte Dezimalstelle formatiert werden.

Der folgende Spielplatzcode zeigt, wie Sie eine erstellen NumberFormatter, die String?von einer Intmit mindestens zwei ganzzahligen Ziffern zurückkehrt:

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

Ich denke, Ihre Antwort ist richtig, wenn Sie Zahlen an mehreren Stellen auf die gleiche Weise formatieren möchten. Da ich nicht danach gefragt habe, habe ich die Antwort von vacawama als die richtige gewählt, aber. Aber danke für die Antwort! :)
Jeehut

@ImanouPetit. Zu Ihrer Information, ich habe dies mit einer minimalen Anzahl von Ziffern 3 verwendet. Wenn ich nicht explizit auspacke, dh formattedNumber = formatter.stringFromNumber (Zähler)! Dann enthalten die Zeichenfolgen Optional ("001"), sodass mein Code zum dynamischen Auswählen eines Bildpfads fehlschlägt. Das Auspacken mit '!' Löst das Problem
Codecowboy

11

Fügen Sie für die linke Auffüllung eine Zeichenfolgenerweiterung wie folgt hinzu:

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

Mit dieser Methode:

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

1
Warum?! Was ist der Vorteil davon?
Mike Glukhov

7

Swift 3.0+

Linke Polsterverlängerung Stringähnlich wie 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
    }
}

Verwendungszweck:

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

1
Dies kann funktionieren oder nicht, wie der Benutzer erwartet, wenn das übergebene withPadArgument mehr als ein einzelnes Zeichen enthält.
nhgrif

4

Swift 5

@imanuo answers ist bereits großartig, aber wenn Sie mit einer Anwendung voller Zahlen arbeiten, können Sie eine Erweiterung wie diese in Betracht ziehen:

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

}

Auf diese Weise können Sie überall anrufen:

String(withInt: 3) 
// prints 03

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

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

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

Erweiterungen FTW .. !! Dies funktionierte auch gut in Swift 4. Für diejenigen von uns, die Schwierigkeiten haben, älteren Code von 3 auf 4 und schließlich auf Swift 5 zu verschieben ... :)
Nick N

3

in Xcode 8.3.2, iOS 10.3 Das ist jetzt gut

Beispiel 1:

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

Beispiel 2:

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

1

Die anderen Antworten sind gut, wenn Sie nur mit Zahlen arbeiten, die die Formatzeichenfolge verwenden. Dies ist jedoch gut, wenn Sie möglicherweise Zeichenfolgen haben, die aufgefüllt werden müssen (obwohl dies zugegebenermaßen etwas anders ist als die gestellte Frage, scheint dies im Geiste ähnlich zu sein). Seien Sie auch vorsichtig, wenn die Saite länger als das Pad ist.

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

Ausgabe "-----a str"


0

Einzelheiten

Xcode 9.0.1, schnell 4.0

Lösungen

Daten

import Foundation

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

Lösung 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"))
}

Lösung 2

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

Lösung 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)")
}

Wie bei Ihrem RepeatElement-Ansatz finden Sie in meiner Antwort das Auffüllen von Zeichenfolgen.
Possen

Diese funktionieren nicht für zweistellige Ints (z. B. 10 wird 010). Auch die ursprüngliche Frage wurde speziell für Lösungen mit Standardbibliotheken gestellt. Die Antwort oben von @ImanouPetit wird bevorzugt.
Cleverbit

-12

Im Gegensatz zu den anderen Antworten, die einen Formatierer verwenden, können Sie vor jeder Zahl in der Schleife auch einfach einen "0" -Text einfügen:

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

Der Formatierer ist jedoch oft besser, wenn Sie für jede einzelne Zahl eine bestimmte Anzahl von Nullen hinzufügen müssen. Wenn Sie jedoch nur eine 0 hinzufügen müssen, ist dies wirklich nur Ihre Wahl.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.