Ведущие нули для Int в Swift

Я хотел бы преобразовать Int в Свифте к String с ведущими нулями. Например, рассмотрим этот код:

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

В настоящее время результатом этого является:

1
2
3

Но я хочу, чтобы это было:

01
02
03

Есть ли чистый способ сделать это в стандартных библиотеках Swift?

12 ответов

Решение

Предполагая, что вам нужно поле длиной 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 поэтому нет необходимости импортировать его снова, если вы уже импортировали Cocoa или же UIKit,


Строка формата может указывать формат нескольких элементов. Например, если вы пытаетесь отформатировать 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

В Swift 4 вы можете выбрать один из трех примеров, показанных ниже, чтобы решить вашу проблему.


# 1. С помощью String "s init(format:_:) инициализатор

Foundation обеспечивает Swift String init(format:_:) инициализатор. init(format:_:) имеет следующую декларацию:

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

Возвращает String объект инициализируется с использованием заданной строки формата в качестве шаблона, в который подставляются остальные значения аргумента.

Следующий код Playground показывает, как создать String отформатирован из Int по крайней мере с двумя целыми числами, используя 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. С помощью String "s init(format:arguments:) инициализатор

Foundation обеспечивает Swift String init(format:arguments:) инициализатор. init(format:arguments:) имеет следующую декларацию:

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

Возвращает String объект инициализируется с использованием заданной строки формата в качестве шаблона, в который подставляются остальные значения аргумента в соответствии с локалью пользователя по умолчанию.

Следующий код Playground показывает, как создать String отформатирован из Int по крайней мере с двумя целыми числами, используя 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, Apple заявляет об этом:

Экземпляры NSNumberFormatter отформатировать текстовое представление ячеек, которые содержат NSNumber объекты и конвертировать текстовые представления числовых значений в NSNumber объекты. Представление включает в себя целые числа, числа с плавающей запятой и двойные числа; числа с плавающей запятой и двойники могут быть отформатированы до указанной десятичной позиции.

Следующий код Playground показывает, как создать 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")

Для заполнения слева добавьте расширение строки, например:

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

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"

Swift 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

Использование новой причудливой расширяемой интерполяции Swift 5:

      extension DefaultStringInterpolation {
    mutating func appendInterpolation(pad value: Int, toWidth width: Int, using paddingCharacter: Character = "0") {
        appendInterpolation(String(format: "%\(paddingCharacter)\(width)d", value))
    }
}

print("I ate \(pad: pieCount, toWidth: 3, using: "0") pies")  // => `I ate 003 pies`

Другие ответы хороши, если вы имеете дело только с числами, использующими строку формата, но это хорошо, когда у вас могут быть строки, которые нужно дополнить (хотя, по общему признанию, они немного отличаются от заданного вопроса, по духу похожи). Также будьте осторожны, если строка длиннее пэда.

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

Выход "-----a str"

Приведенный ниже код генерирует строку из 3 цифр с отступом 0 впереди:

      import Foundation

var randomInt = Int.random(in: 0..<1000)
var str = String(randomInt)
var paddingZero = String(repeating: "0", count: 3 - str.count)

print(str, str.count, paddingZero + str)

Выход:

      5 1 005
88 2 088
647 3 647

В Xcode 8.3.2, iOS 10.3 это хорошо сейчас

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

Swift 4* и выше, вы также можете попробовать это:

func leftPadding(valueString: String, toLength: Int, withPad: String = " ") -> String {
        guard toLength > valueString.count else { return valueString }
        
        let padding = String(repeating: withPad, count: toLength - valueString.count)
        return padding + valueString
    }

вызвать функцию:

leftPadding(valueString: "12", toLength: 5, withPad: "0")

Выход:"00012"

подробности

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

В отличие от других ответов, использующих средство форматирования, вы также можете просто добавить текст "0" перед каждым числом внутри цикла, например:

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

Но форматирование часто лучше, когда вы должны добавить предполагаемое количество 0 для каждого отдельного числа. Если вам нужно только добавить один 0, тогда это действительно ваш выбор.

Другие вопросы по тегам