Провідні нулі для Int in Swift


305

Я хотів би перетворити Intв Swift у Stringпровідні нулі. Наприклад, розгляньте цей код:

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

В даний час його результат:

1
2
3

Але я хочу, щоб це було:

01
02
03

Чи є чистий спосіб зробити це в стандартних бібліотеках Swift?

Відповіді:


670

Припустимо, що ви хочете довжину поля 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

2
Хоча це не є частиною Свіфта, воно насправді виглядає дуже чисто. Я думаю, що просто не існує рідного способу цього швидко, тому це, можливо, зараз є найближчим. Дякую, vacawama. :)
Jeehut

1
До речі: Якщо я хотів би лише один нуль перед своїм номером, я вибрав би println("0\(myInt)")вашу пропозицію. Це використовує нативний клас String Swift замість того, щоб пройти формат NSString.
Jeehut

6
Корисно, поки ви не дістанетесь до "10", хе-хе
Хосе М Пан

7
String(format: "%03d", myInt)дасть тобі "000", "001", ... , "099", "100".
vacawama

1
Проблема цих проблем, якщо таке значення -3, -9має місце, воно все одно повертає те саме, що не веде до нуля.
Codetard

139

За допомогою Swift 5 ви можете вибрати один із трьох наведених нижче прикладів для вирішення своєї проблеми.


№1. Використання String«s init(format:_:)ініціалізатор

Foundationзабезпечує Swift Stringв init(format:_:)ініціалізатор. init(format:_:)має таку заяву:

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

Повертає Stringоб'єкт, ініціалізований за допомогою заданого рядка формату як шаблону, на який підміняються решта значень аргументу.

Наведений нижче код майданчика показує, як створити 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об'єкт, ініціалізований за допомогою заданого рядка формату в якості шаблону, в який інші параметри аргументу підміняються відповідно до мови за замовчуванням користувача.

Наведений нижче код майданчика показує, як створити 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об'єкти. Представлення охоплює цілі числа, плаваючі та парні; поплавці та подвійні елементи можуть бути відформатовані до заданої десяткової позиції.

Наступний код показує , як майданчик створити 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")

Я думаю, що ваша відповідь правильна, коли ви хочете форматувати номери однаково в декількох місцях. Оскільки я не просив цього, я вибрав відповідь вакавами як правильну, але. Але дякую за відповідь! :)
Jeehut

@ImanouPetit FYI, я використав це з мінімальною кількістю цифр 3. Якщо я не скажу явно, тобто дозволь formattedNumber = formatter.stringFromNumber (лічильник)! то рядки містять необов'язково ("001"), тому мій код динамічного вибору шляху зображення не вдається. Розгортання "!"
Вирішує

11

Для лівої підкладки додайте розширення рядка таким чином:

Швидкий 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
    }
}

Швидкий 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
чому ?! в чому перевага цього?
Майк Глухов

7

Швидкий 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"

1
Це може бути, а може і не працювати, як очікує користувач, якщо withPadпереданий аргумент більше одного символу.
nhgrif

4

Швидкий 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

розширення FTW .. !! Це також спрацювало чудово у Swift 4. Для тих, хто намагається перенести старіший код з 3, на 4 та, врешті-решт, на Swift 5 ... :)
Nick N

3

в Xcode 8.3.2, iOS 10.3 Це добре зараз

Зразок1:

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

Зразок2:

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, швидкий 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)")
}

Як і у вашому підході на повторення, дивіться мою відповідь на накладення рядків.
possen

Вони не працюватимуть для двоцифрових вводів (наприклад, 10 стає 010). Також оригінальне запитання було задано спеціально для рішень із залученням стандартних бібліотек. Відповідь вище від @ImanouPetit є кращою.
кмітливий

-12

На відміну від інших відповідей, які використовують формат, ви також можете просто додати текст "0" перед кожним номером всередині циклу, як це:

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

Але форматування часто краще, якщо вам доведеться додати припущену кількість 0 у кожне окреме число. Якщо вам потрібно лише додати один 0, то це справді лише ваш вибір.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.