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

229

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

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

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

1
2
3

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

01
02
03

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

Теги:
string
type-conversion
int

8 ответов

534
Лучший ответ

Предполагая, что вам нужно поле длиной 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
  • 1
    Хотя это не является частью Swift, на самом деле это выглядит очень чисто. Я думаю, что у Swift нет родного способа сделать это, так что это может быть самым близким на данный момент. Спасибо, Vacawama. :)
  • 1
    Кстати: если бы я просто хотел один ноль перед моим номером, я бы выбрал println("0\(myInt)") вашего предложения. Это будет использовать Swift нативный класс String вместо того, чтобы проходить форматирование NSString.
Показать ещё 8 комментариев
121

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


# 1. Использование String 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 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")
  • 0
    Я думаю, что ваш ответ правильный, если вы хотите отформатировать числа одинаково в нескольких местах. Поскольку я не просил об этом, я выбрал правильный ответ Вакавамы, но. Но спасибо за ответ! :)
  • 0
    @ImanouPetit. К вашему сведению, я использовал это с минимальным количеством цифр 3. Если я не разверну явным образом, т.е. пусть formattedNumber = formatter.stringFromNumber (counter)! тогда строки содержат Optional ("001"), поэтому мой код для динамического выбора пути к изображению не работает. Распаковка с "!" Решает проблему
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
    Зачем?! в чем преимущество этого?
6

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"
  • 0
    Это может или не может работать так, как ожидает пользователь, если withPad аргумент withPad содержит более одного символа.
2

в 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
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)")
}
  • 0
    Как и ваш подход repeatElement, см. Мой ответ для заполнения строк.
  • 0
    Они не будут работать для двухзначных чисел (например, 10 становится 010). Также оригинальный вопрос задавался специально для решений с участием стандартных библиотек. Ответ выше @ImanouPetit является предпочтительным.
-12

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню