Zeros à esquerda para Int em Swift


305

Gostaria de converter um Intem Swift para um Stringcom zeros à esquerda. Por exemplo, considere este código:

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

Atualmente, o resultado é:

1
2
3

Mas eu quero que seja:

01
02
03

Existe uma maneira limpa de fazer isso nas bibliotecas padrão Swift?

Respostas:


670

Supondo que você queira um tamanho de campo 2 com zeros à esquerda, você faria isso:

import Foundation

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

resultado:

01
02
03

Isso requer import Foundationque, tecnicamente, não faça parte da linguagem Swift, mas um recurso fornecido pela Foundationestrutura. Observe que os dois são incluídos import UIKite, portanto, não é necessário importá-lo novamente se você já importou ou .import CocoaFoundationCocoaUIKit


A cadeia de formato pode especificar o formato de vários itens. Por exemplo, se você estiver tentando formatar 3horas, 15minutos e 7segundos, 03:15:07poderá fazer o seguinte:

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

resultado:

03:15:07

2
Embora isso não faça parte do Swift, ele realmente parece muito limpo. Eu acho que simplesmente não existe uma maneira nativa do Swift de fazer isso, então isso pode ser o mais próximo por enquanto. Obrigado vacawama. :)
Jeehut

1
A propósito: se eu quisesse apenas um zero na frente do meu número, escolheria println("0\(myInt)")a sua sugestão. Isso usaria a classe String nativa do Swift, em vez de passar pela formatação NSString.
Jeehut 29/08/14

6
É útil até você chegar ao "10", hehe
Jose M Pan

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

1
O problema é o seguinte, se -3, -9ocorrer um valor semelhante , ele ainda retornará o mesmo sem um zero inicial.
Codetard 28/09/18

139

Com o Swift 5, você pode escolher um dos três exemplos mostrados abaixo para resolver seu problema.


# 1 Usando Stringo init(format:_:)inicializador

Foundationfornece ao Swift Stringum init(format:_:)inicializador. init(format:_:)tem a seguinte declaração:

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

Retorna um Stringobjeto inicializado usando uma determinada string de formato como um modelo no qual os valores restantes do argumento são substituídos.

O seguinte código do Playground mostra como criar um Stringformatado Intcom pelo menos dois dígitos inteiros 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 Stringo init(format:arguments:)inicializador

Foundationfornece ao Swift Stringum init(format:arguments:)inicializador. init(format:arguments:)tem a seguinte declaração:

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

Retorna um Stringobjeto inicializado usando uma determinada string de formato como um modelo no qual os valores restantes do argumento são substituídos de acordo com o código de idioma padrão do usuário.

O seguinte código do Playground mostra como criar um Stringformatado Intcom pelo menos dois dígitos inteiros 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 UsandoNumberFormatter

Fundação fornece NumberFormatter. A Apple afirma sobre isso:

Instâncias de NSNumberFormatterformatar a representação textual de células que contêm NSNumberobjetos e converter representações textuais de valores numéricos em NSNumberobjetos. A representação abrange números inteiros, flutuadores e duplos; flutuadores e duplos podem ser formatados para uma posição decimal especificada.

O código do Playground a seguir mostra como criar um NumberFormatterque retorna String?de um Intcom pelo menos dois dígitos inteiros:

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

Acho que sua resposta está correta quando você deseja formatar números da mesma maneira em vários locais. Como não pedi isso, escolhi a resposta de vacawama como a correta, mas. Mas obrigado pela resposta! :)
Jeehut

@ImanouPetit. Para sua informação, usei isso com um número mínimo de dígitos 3. Se eu não desembrulhar explicitamente, ou seja, deixe formattedNumber = formatter.stringFromNumber (counter)! as seqüências contêm Opcional ("001"), portanto, meu código para escolher dinamicamente um caminho de imagem falha. Desembrulhar com '! "Resolve o problema
codecowboy 15/07/2015

11

Para o preenchimento esquerdo, adicione uma extensão de string como esta:

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

Usando este método:

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

1
porque?! qual a vantagem disso?
Mike Glukhov

7

Swift 3.0+

Padding-left Stringextensão semelhante à padding(toLength:withPad:startingAt:)deFoundation

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
Isso pode ou não funcionar como o usuário espera se o withPadargumento passado for mais do que um único caractere.
Nhgrif 7/08

4

Swift 5

O @imanuo answers já é ótimo, mas se você estiver trabalhando com um aplicativo cheio de números, considere uma extensão como esta:

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

}

Dessa forma, você pode ligar para qualquer lugar:

String(withInt: 3) 
// prints 03

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

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

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

extensões FTW .. !! Esta multa também trabalhou na Swift 4. Para aqueles de nós lutando para mover o código mais velho, de 3, 4, e, eventualmente, a Swift 5 ... :)
Nick N

3

no Xcode 8.3.2, iOS 10.3 Isso é bom agora

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

As outras respostas são boas se você estiver lidando apenas com números usando a sequência de formatação, mas isso é bom quando você pode ter sequências que precisam ser preenchidas (embora seja um pouco diferente da pergunta feita, parece similar em espírito). Além disso, tenha cuidado se a corda for maior que a almofada.

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

Resultado "-----a str"


0

Detalhes

Xcode 9.0.1, swift 4.0

Soluções

Dados

import Foundation

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

Solução 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"))
}

Solução 2

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

Solução 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)")
}

Como sua abordagem repeatElement, veja minha resposta para cadeias de preenchimento.
possen

Isso não funcionará para entradas de dois dígitos (por exemplo, 10 torna-se 010). Também a pergunta original pediu especificamente soluções envolvendo bibliotecas padrão. A resposta acima de @ImanouPetit é preferida.
Cleverbit

-12

Diferente das outras respostas que usam um formatador, você também pode adicionar um texto "0" na frente de cada número dentro do loop, assim:

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

Mas o formatador geralmente é melhor quando você precisa adicionar, suponha uma quantidade designada de 0s para cada número separado. No entanto, se você só precisar adicionar um 0, é apenas uma escolha.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.