Memimpin nol untuk Int di Swift

305

Saya ingin mengonversi Intdalam Swift menjadi Stringdengan nol di depan. Sebagai contoh, pertimbangkan kode ini:

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

Saat ini hasilnya adalah:

1
2
3

Tapi saya ingin:

01
02
03

Apakah ada cara bersih untuk melakukan ini di dalam perpustakaan standar Swift?

Astaga
sumber

Jawaban:

670

Dengan asumsi Anda menginginkan panjang bidang 2 dengan nol di depan, Anda akan melakukan ini:

import Foundation

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

keluaran:

01
02
03

Ini membutuhkan secara import Foundationteknis itu bukan bagian dari bahasa Swift tetapi kemampuan yang disediakan oleh Foundationkerangka kerja. Perhatikan bahwa keduanya import UIKitdan import Cocoatermasuk Foundationsehingga tidak perlu mengimpor lagi jika Anda sudah mengimpor Cocoaatau UIKit.


String format dapat menentukan format beberapa item. Misalnya, jika Anda mencoba memformat 3jam, 15menit , dan 7detik, 03:15:07Anda dapat melakukannya seperti ini:

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

keluaran:

03:15:07
vacawama
sumber
2
Meskipun ini bukan bagian dari Swift sebenarnya terlihat sangat bersih. Saya pikir tidak ada cara asli Swift untuk melakukan ini jadi ini mungkin yang terdekat untuk saat ini. Terima kasih, vacawama. :)
Jeehut
1
Ngomong-ngomong: Jika saya hanya ingin satu nol di depan nomor saya, saya akan memilih println("0\(myInt)")atas saran Anda. Itu akan menggunakan kelas String asli Swift bukannya melalui pemformatan NSString.
Jeehut
6
Berguna sampai Anda mendapatkan "10", hehe
Jose M Pan
7
String(format: "%03d", myInt)akan memberimu "000", "001", ... , "099", "100".
vacawama
1
Ini masalah jika nilai seperti -3, -9terjadi, masih mengembalikan yang sama tanpa nol di depan.
Codetard
139

Dengan Swift 5, Anda dapat memilih salah satu dari tiga contoh di bawah ini untuk menyelesaikan masalah Anda.


# 1. Menggunakan String's init(format:_:)initializer

Foundationmenyediakan Swift Stringsebuah init(format:_:)initializer. init(format:_:)memiliki deklarasi berikut:

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

Mengembalikan Stringobjek yang diinisialisasi dengan menggunakan string format yang diberikan sebagai templat di mana nilai argumen yang tersisa diganti.

Kode Playground berikut menunjukkan cara membuat yang Stringdiformat Intdengan setidaknya dua digit bilangan bulat dengan menggunakan 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. Menggunakan String's init(format:arguments:)initializer

Foundationmenyediakan Swift Stringsebuah init(format:arguments:)initializer. init(format:arguments:)memiliki deklarasi berikut:

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

Mengembalikan Stringobjek yang diinisialisasi dengan menggunakan string format yang diberikan sebagai templat ke mana nilai argumen yang tersisa diganti sesuai dengan lokal default pengguna.

Kode Playground berikut menunjukkan cara membuat yang Stringdiformat Intdengan setidaknya dua digit bilangan bulat dengan menggunakan 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. MenggunakanNumberFormatter

Yayasan menyediakan NumberFormatter. Apple menyatakan tentang itu:

Contoh NSNumberFormatterformat representasi tekstual sel yang berisi NSNumberobjek dan mengkonversi representasi tekstual dari nilai numerik menjadi NSNumberobjek. Representasi meliputi bilangan bulat, mengapung, dan ganda; pelampung dan ganda dapat diformat ke posisi desimal yang ditentukan.

Kode Playground berikut menunjukkan cara membuat NumberFormatteryang kembali String?dari Intdengan setidaknya dua digit bilangan bulat:

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")
Imanou Petit
sumber
Saya pikir jawaban Anda benar ketika Anda ingin memformat angka dengan cara yang sama di banyak tempat. Karena saya tidak meminta itu, saya memilih jawaban vacawama sebagai jawaban yang benar. Tapi terima kasih atas jawabannya! :)
Jeehut
@ImanouPetit. FYI, saya menggunakan ini dengan angka angka minimum 3. Jika saya tidak membuka secara eksplisit yaitu membiarkan formattedNumber = formatter.stringFromNumber (counter)! maka string berisi Opsional ("001") sehingga kode saya untuk secara dinamis memilih jalur gambar gagal. Membuka gulungan dengan '! "
Memecahkan
11

Untuk bantalan kiri tambahkan ekstensi string seperti ini:

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

Menggunakan metode ini:

for myInt in 1...3 {
    print("\(myInt)".padLeft(totalWidth: 2, with: "0"))
}
Kiran P Nair
sumber
1
Mengapa?! apa keuntungan dari ini?
Mike Glukhov
7

Swift 3.0+

StringEkstensi padding kiri mirip dengan padding(toLength:withPad:startingAt:)diFoundation

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

Pemakaian:

let s = String(123)
s.leftPadding(toLength: 8, withPad: "0") // "00000123"
John Cromie
sumber
1
Ini mungkin atau mungkin tidak berfungsi seperti yang diharapkan pengguna jika withPadargumen yang diberikan lebih dari satu karakter.
nhgrif
4

Cepat 5

@imanuo jawaban sudah bagus, tetapi jika Anda bekerja dengan aplikasi yang penuh angka, Anda dapat mempertimbangkan ekstensi seperti ini:

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

}

Dengan cara ini Anda dapat menelepon ke mana saja:

String(withInt: 3) 
// prints 03

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

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

"54".leadingZeros(3)
// prints 054
Luca Davanzo
sumber
ekstensi FTW .. !! Ini juga berfungsi dengan baik di Swift 4. Bagi kita yang berjuang untuk memindahkan kode lama dari 3, ke 4, dan akhirnya ke Swift 5 ... :)
Nick N
3

di Xcode 8.3.2, iOS 10.3 Itu bagus untuk saat ini

Contoh1:

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

Contoh2:

let dayMoveRaw = 55 
let dayMove = String(format: "%02d", arguments: [dayMoveRaw])
print(dayMove) // 55
Steffen
sumber
1

Jawaban lainnya bagus jika Anda hanya berurusan dengan angka menggunakan format string, tetapi ini bagus ketika Anda mungkin memiliki string yang perlu diisi (meskipun diakui sedikit berbeda dari pertanyaan yang diajukan, tampaknya semangatnya serupa). Juga, berhati-hatilah jika tali lebih panjang dari pad.

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

Keluaran "-----a str"

possen
sumber
0

Detail

Xcode 9.0.1, cepat 4.0

Solusi

Data

import Foundation

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

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

Solusi 2

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

Solusi 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)")
}
Bodnarchuk dengan mudah
sumber
Seperti pendekatan repeatElement Anda, lihat jawaban saya untuk string padding.
possen
Ini tidak akan berfungsi untuk dua digit int (mis. 10 menjadi 010). Juga pertanyaan awal yang diajukan secara khusus untuk solusi yang melibatkan Perpustakaan Standar. Jawaban di atas oleh @ImanouPetit lebih disukai.
cleverbit
-12

Berbeda dengan jawaban lain yang menggunakan formatter, Anda juga bisa menambahkan teks "0" di depan setiap angka di dalam loop, seperti ini:

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

Tapi formatter sering lebih baik ketika Anda harus menambahkan anggaplah jumlah yang ditentukan 0s untuk setiap nomor terpisah. Jika Anda hanya perlu menambahkan satu 0, maka itu benar-benar hanya pilihan Anda.

Eric Zhou
sumber