Số không hàng đầu cho Int trong Swift


305

Tôi muốn chuyển đổi một Inttrong Swift thành một Stringsố không hàng đầu. Ví dụ, hãy xem xét mã này:

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

Hiện tại kết quả của nó là:

1
2
3

Nhưng tôi muốn nó là:

01
02
03

Có cách nào rõ ràng để làm điều này trong các thư viện tiêu chuẩn Swift không?

Câu trả lời:


670

Giả sử bạn muốn có độ dài trường là 2 với các số 0 đứng đầu, bạn sẽ làm điều này:

import Foundation

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

đầu ra:

01
02
03

Điều này đòi hỏi import Foundationrất kỹ thuật, nó không phải là một phần của ngôn ngữ Swift mà là một khả năng được cung cấp bởi Foundationkhung. Lưu ý rằng cả hai import UIKitimport Cocoabao gồm Foundationvì vậy không cần thiết phải nhập lại nếu bạn đã nhập Cocoahoặc UIKit.


Chuỗi định dạng có thể chỉ định định dạng của nhiều mục. Chẳng hạn, nếu bạn đang cố gắng định dạng 3giờ, 15phút và 7giây, 03:15:07bạn có thể làm như thế này:

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

đầu ra:

03:15:07

2
Mặc dù đây không phải là một phần của Swift nhưng nó thực sự trông rất sạch sẽ. Tôi nghĩ rằng không có cách bản địa nào của Swift để làm điều này vì vậy đây có thể là cách gần nhất. Cảm ơn bạn, vacawama. :)
Jeehut

1
Nhân tiện: Nếu tôi chỉ muốn một số 0 trước số tôi đã chọn println("0\(myInt)")qua đề xuất của bạn. Điều đó sẽ sử dụng lớp Chuỗi gốc Swift thay vì đi qua định dạng NSString.
Jeehut

6
Rất hữu ích cho đến khi bạn đạt được "10", hehe
Jose M Pan

7
String(format: "%03d", myInt)sẽ cung cấp cho bạn "000", "001", ... , "099", "100".
vacawama

1
Đây là vấn đề nếu giá trị như -3, -9xảy ra, Nó vẫn trả về như cũ mà không có số 0 đứng đầu.
Codetard

139

Với Swift 5, bạn có thể chọn một trong ba ví dụ được hiển thị bên dưới để giải quyết vấn đề của mình.


# 1. Sử dụng String's init(format:_:)initializer

Foundationcung cấp cho Swift Stringmột trình init(format:_:)khởi tạo. init(format:_:)có tuyên bố sau:

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

Trả về một Stringđối tượng được khởi tạo bằng cách sử dụng một chuỗi định dạng đã cho làm mẫu mà các giá trị đối số còn lại được thay thế.

Mã Playground sau đây cho biết cách tạo Stringđịnh dạng từ Intít nhất hai chữ số nguyên bằng cách sử dụng 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. Sử dụng String's init(format:arguments:)initializer

Foundationcung cấp cho Swift Stringmột trình init(format:arguments:)khởi tạo. init(format:arguments:)có tuyên bố sau:

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

Trả về một Stringđối tượng được khởi tạo bằng cách sử dụng một chuỗi định dạng đã cho làm mẫu mà các giá trị đối số còn lại được thay thế theo ngôn ngữ mặc định của người dùng.

Mã Playground sau đây cho biết cách tạo Stringđịnh dạng từ Intít nhất hai chữ số nguyên bằng cách sử dụng 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. Sử dụngNumberFormatter

Foundation cung cấp NumberFormatter. Apple tuyên bố về điều đó:

Thể hiện NSNumberFormatterđịnh dạng biểu diễn văn bản của các ô có chứa NSNumbercác đối tượng và chuyển đổi biểu diễn văn bản của các giá trị số thành NSNumbercác đối tượng. Các đại diện bao gồm số nguyên, phao và đôi; phao và đôi có thể được định dạng đến một vị trí thập phân được chỉ định.

Mã Playground sau đây cho biết cách tạo một NumberFormattertrả về String?từ a Intcó ít nhất hai chữ số nguyên:

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

Tôi nghĩ rằng câu trả lời của bạn là đúng khi bạn muốn định dạng số theo cùng một cách tại nhiều nơi. Vì tôi đã không hỏi rằng tôi đã chọn câu trả lời của vacawama là đúng nhưng. Nhưng cảm ơn bạn đã trả lời! :)
Jeehut

@ImanouPetit. FYI, tôi đã sử dụng số này với các chữ số số tối thiểu 3. Nếu tôi không rõ ràng không sẵn sàng tức là hãy để formattedNumber = formatter.opesFromNumber (bộ đếm)! sau đó các chuỗi chứa Tùy chọn ("001") để mã của tôi tự động chọn đường dẫn hình ảnh không thành công. Unwrapping với '! "Giải quyết vấn đề
codecowboy

11

Đối với phần đệm bên trái, thêm phần mở rộng chuỗi như thế này:

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

Sử dụng phương pháp này:

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

1
tại sao?! lợi thế của điều này là gì?
Mike Glukhov

7

Swift 3.0+

StringPhần mở rộng phần đệm bên trái tương tự như padding(toLength:withPad:startingAt:)trongFoundation

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

Sử dụng:

let s = String(123)
s.leftPadding(toLength: 8, withPad: "0") // "00000123"

1
Điều này có thể hoặc không thể hoạt động như người dùng mong đợi nếu withPadđối số được truyền nhiều hơn một ký tự.
nhgrif

4

Swift 5

Câu trả lời @imanuo đã rất tuyệt, nhưng nếu bạn đang làm việc với một ứng dụng đầy số, bạn có thể xem xét một tiện ích mở rộng như thế này:

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

}

Bằng cách này, bạn có thể gọi bất cứ nơi nào:

String(withInt: 3) 
// prints 03

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

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

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

tiện ích mở rộng FTW .. !! Điều này cũng hoạt động tốt trong Swift 4. Đối với những người trong chúng ta đang vật lộn để chuyển mã cũ hơn từ 3, sang 4 và cuối cùng sang Swift 5 ... :)
Nick N

3

trong Xcode 8.3.2, iOS 10.3 Thats là tốt

Mẫu1:

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

Mẫu2:

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

1

Các câu trả lời khác là tốt nếu bạn chỉ xử lý các số bằng chuỗi định dạng, nhưng điều này tốt khi bạn có thể có các chuỗi cần được đệm (mặc dù phải thừa nhận một chút khác so với câu hỏi được hỏi, có vẻ tương tự về mặt tinh thần). Ngoài ra, hãy cẩn thận nếu chuỗi dài hơn pad.

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

Đầu ra "-----a str"


0

Chi tiết

Xcode 9.0.1, nhanh 4.0

Các giải pháp

Dữ liệu

import Foundation

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

Giải pháp 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"))
}

Giải pháp 2

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

Giải pháp 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)")
}

Giống như phương pháp lặp lại của bạn, xem câu trả lời của tôi cho chuỗi đệm.
sở hữu

Chúng sẽ không hoạt động đối với hai chữ số int (ví dụ: 10 trở thành 010). Ngoài ra câu hỏi ban đầu được hỏi cụ thể cho các giải pháp liên quan đến Thư viện tiêu chuẩn. Câu trả lời ở trên của @ImanouPetit được ưu tiên.
smartbit 30/12/18

-12

Không giống như các câu trả lời khác sử dụng một trình định dạng, bạn cũng có thể chỉ cần thêm một văn bản "0" vào trước mỗi số bên trong vòng lặp, như sau:

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

Nhưng định dạng thường tốt hơn khi bạn phải thêm một số 0 được chỉ định cho mỗi số riêng biệt. Tuy nhiên, nếu bạn chỉ cần thêm một 0, thì đó thực sự chỉ là lựa chọn của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.