เลขศูนย์นำหน้าสำหรับ Int in Swift


305

ฉันต้องการแปลงเป็นIntSwift เป็น a 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ดังนั้นจึงไม่จำเป็นที่จะต้องนำเข้าอีกครั้งหากคุณได้นำเข้าแล้วหรือCocoaUIKit


สตริงรูปแบบสามารถระบุรูปแบบของหลายรายการ ตัวอย่างเช่นหากคุณพยายามจัดรูปแบบ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
แม้ว่านี่ไม่ใช่ส่วนหนึ่งของ Swift จริงๆแล้วมันดูสะอาดมาก ฉันคิดว่ามันไม่ใช่วิธีการดั้งเดิมในการทำสิ่งนี้อย่างรวดเร็วดังนั้นสิ่งนี้อาจจะใกล้เคียงที่สุดในตอนนี้ ขอบคุณ vacawama :)
Jeehut

1
โดยวิธีการ: ถ้าฉันต้องการเพียงศูนย์เดียวต่อหน้าหมายเลขของฉันฉันจะเลือกprintln("0\(myInt)")มากกว่าข้อเสนอแนะของคุณ นั่นจะใช้คลาส String ของ Swift ดั้งเดิมแทนการผ่านการจัดรูปแบบ NSString
Jeehut

6
มีประโยชน์จนกว่าคุณจะถึง "10" ฮิฮิ
Jose M Pan

7
String(format: "%03d", myInt)"000", "001", ... , "099", "100"จะทำให้คุณ
vacawama

1
ปัญหาเหล่านี้หากค่าที่ต้องการ-3, -9เกิดขึ้นมันยังคงส่งกลับเหมือนเดิมโดยไม่มีศูนย์นำหน้า
Codetard

139

ด้วย Swift 5 คุณสามารถเลือกหนึ่งในสามตัวอย่างที่แสดงด้านล่างเพื่อแก้ปัญหาของคุณ


# 1 ใช้String's init(format:_:)initializer

Foundationให้ Swift Stringa init(format:_:)initializer 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:)initializer

Foundationให้ Swift Stringa init(format:arguments:)initializer 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 ต่อไปนี้แสดงวิธีสร้าง a NumberFormatterที่ส่งคืนString?จาก a 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")

ฉันคิดว่าคำตอบของคุณถูกต้องเมื่อคุณต้องการจัดรูปแบบตัวเลขแบบเดียวกันในหลาย ๆ ที่ ในขณะที่ฉันไม่ได้ถามว่าฉันเลือกคำตอบของ vacawama ว่าถูกต้อง แต่ แต่ขอบคุณสำหรับคำตอบ! :)
Jeehut

@ImanouPetit FYI ฉันใช้สิ่งนี้กับตัวเลขหลักขั้นต่ำ 3 หากฉันไม่ได้แกะอย่างชัดเจนนั่นคือให้ formattedNumber = formatter.stringFromNumber (ตัวนับ)! ดังนั้นสตริงจึงมีตัวเลือก ("001") ดังนั้นรหัสของฉันในการเลือกเส้นทางภาพจึงล้มเหลว แกะ '! "แก้ปัญหา
codecowboy

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
ทำไม?! อะไรคือข้อดีของสิ่งนี้
Mike Glukhov

7

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"

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 ขอบคุณตอนนี้

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

เช่นเดียวกับวิธี repeatElement ของคุณดูคำตอบของฉันสำหรับการเติมสตริง
อยู่

สิ่งเหล่านี้จะไม่ทำงานสำหรับ ints สองหลัก (เช่น 10 กลายเป็น 010) อีกทั้งคำถามเดิมถามโดยเฉพาะสำหรับการแก้ปัญหาที่เกี่ยวข้องกับห้องสมุดมาตรฐาน คำตอบข้างต้นโดย @ImanouPetit เป็นที่ต้องการ
cleverbit

-12

ไม่เหมือนกับคำตอบอื่น ๆ ที่ใช้ตัวจัดรูปแบบคุณยังสามารถเพิ่มข้อความ "0" ที่อยู่ด้านหน้าของแต่ละหมายเลขภายในวงได้เช่นนี้

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

แต่ตัวจัดรูปแบบมักจะดีกว่าเมื่อคุณต้องเพิ่มสมมติว่าจำนวน 0 ที่กำหนดสำหรับแต่ละหมายเลขแยก หากคุณต้องการเพิ่ม 0 เพียงหนึ่งเดียวนั่นเป็นเพียงการเลือกของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.