Zeri iniziali per Int in Swift


305

Vorrei convertire un Intin Swift in un Stringcon zeri iniziali. Ad esempio, considera questo codice:

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

Attualmente il risultato è:

1
2
3

Ma voglio che sia:

01
02
03

Esiste un modo pulito per farlo all'interno delle librerie standard di Swift?

Risposte:


670

Supponendo che tu voglia una lunghezza del campo di 2 con zeri iniziali, dovresti farlo:

import Foundation

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

produzione:

01
02
03

Ciò richiede import Foundationtecnicamente che non fa parte del linguaggio Swift ma una funzionalità fornita dal Foundationframework. Nota che entrambi import UIKite import Cocoaincludi Foundationquindi non è necessario importarlo di nuovo se hai già importato Cocoao UIKit.


La stringa di formato può specificare il formato di più elementi. Ad esempio, se stai cercando di formattare 3ore, 15minuti e 7secondi, 03:15:07potresti farlo in questo modo:

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

produzione:

03:15:07

2
Anche se questo non fa parte di Swift, in realtà sembra molto pulito. Penso che non ci sia un modo nativo di Swift per farlo, quindi questo potrebbe essere il più vicino per ora. Grazie vacawama. :)
Jeehut,

1
A proposito: se volevo solo un singolo zero davanti al mio numero, avrei scelto println("0\(myInt)")il tuo suggerimento. Questo userebbe la classe String nativa di Swift invece di passare attraverso la formattazione NSString.
Jeehut,

6
È utile fino ad arrivare a "10", hehe
Jose M Pan

7
String(format: "%03d", myInt)ti darà "000", "001", ... , "099", "100".
vacawama,

1
Questo è un problema se si -3, -9verifica un valore simile , restituisce comunque lo stesso senza zero iniziale.
Codetard,

139

Con Swift 5, puoi scegliere uno dei tre esempi mostrati di seguito per risolvere il tuo problema.


# 1. Usando Stringl' init(format:_:)inizializzatore

Foundationfornisce a Swift Stringun init(format:_:)inizializzatore. init(format:_:)ha la seguente dichiarazione:

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

Restituisce un Stringoggetto inizializzato utilizzando una determinata stringa di formato come modello in cui vengono sostituiti i valori degli argomenti rimanenti.

Il seguente codice Playground mostra come creare un Stringformato da Intalmeno due cifre intere usando 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. Usando Stringl' init(format:arguments:)inizializzatore

Foundationfornisce a Swift Stringun init(format:arguments:)inizializzatore. init(format:arguments:)ha la seguente dichiarazione:

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

Restituisce un Stringoggetto inizializzato utilizzando una determinata stringa di formato come modello in cui i valori degli argomenti rimanenti vengono sostituiti in base alle impostazioni internazionali predefinite dell'utente.

Il seguente codice Playground mostra come creare un Stringformato da Intalmeno due cifre intere usando 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. utilizzandoNumberFormatter

Fondazione fornisce NumberFormatter. Apple afferma al riguardo:

Istanze di NSNumberFormatterformattazione della rappresentazione testuale di celle che contengono NSNumberoggetti e conversione di rappresentazioni testuali di valori numerici in NSNumberoggetti. La rappresentazione comprende numeri interi, float e doppi; float e doppi possono essere formattati in una posizione decimale specificata.

Il seguente codice Playground mostra come creare un NumberFormatterche ritorni String?da a Intcon almeno due cifre intere:

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

Penso che la tua risposta sia giusta quando vuoi formattare i numeri allo stesso modo in più punti. Dato che non l'ho chiesto, ho scelto la risposta di vacawama come corretta ma. Ma grazie per la risposta! :)
Jeehut,

@ImanouPetit. Cordiali saluti, l'ho usato con un numero minimo di cifre 3. Se non lo scarto in modo esplicito, ovvero lascia formattedNumber = formatter.stringFromNumber (counter)! quindi le stringhe contengono Opzionale ("001"), quindi il mio codice per scegliere dinamicamente un percorso di immagine non riesce. Scartare con "!" Risolve il problema
codecowboy,

11

Per il padding sinistro aggiungi un'estensione di stringa come questa:

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

Utilizzando questo metodo:

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

1
perché?! qual è il vantaggio di questo?
Mike Glukhov,

7

Swift 3.0+

StringEstensione imbottitura sinistra simile a 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
    }
}

Uso:

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

1
Ciò può funzionare o meno come previsto dall'utente se l' withPadargomento passato è più di un singolo carattere.
nhgrif,

4

Swift 5

@imanuo risponde è già eccezionale, ma se stai lavorando con un'applicazione piena di numeri, puoi considerare un'estensione come questa:

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

In questo modo puoi chiamare ovunque:

String(withInt: 3) 
// prints 03

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

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

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

estensioni FTW .. !! Questo ha funzionato bene anche in Swift 4. Per quelli di noi che lottano per spostare il codice precedente da 3, a 4, e infine su Swift 5 ... :)
Nick N,

3

in Xcode 8.3.2, iOS 10.3 Questo è buono per ora

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

1

Le altre risposte sono buone se hai a che fare solo con numeri che usano la stringa di formato, ma questo è utile quando potresti avere stringhe che devono essere riempite (anche se è vero che sono leggermente diverse dalla domanda posta, sembrano simili nello spirito). Inoltre, fai attenzione se la stringa è più lunga del pad.

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

Produzione "-----a str"


0

Dettagli

Xcode 9.0.1, rapido 4.0

soluzioni

Dati

import Foundation

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

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

Soluzione 2

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

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

Come il tuo approccio repeatElement, vedi la mia risposta per le stringhe di riempimento.
Possed

Questi non funzioneranno per ints a due cifre (es. 10 diventa 010). Anche la domanda originale ha chiesto specificamente soluzioni che coinvolgono le librerie standard. La risposta sopra di @ImanouPetit è preferita.
Cleverbit

-12

A differenza delle altre risposte che usano un formattatore, puoi anche aggiungere un testo "0" davanti a ciascun numero all'interno del ciclo, in questo modo:

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

Ma il formatter è spesso migliore quando devi aggiungere supponiamo che un numero designato di 0s per ogni numero separato. Se hai solo bisogno di aggiungere uno 0, però, è davvero solo la tua scelta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.