Swift - จะลบทศนิยมออกจากทศนิยมได้อย่างไรถ้าทศนิยมเท่ากับ 0?


90

ฉันกำลังแสดงระยะทางด้วยทศนิยมหนึ่งตำแหน่งและฉันต้องการลบทศนิยมนี้ในกรณีที่มีค่าเท่ากับ 0 (เช่น 1200.0Km) ฉันจะทำอย่างรวดเร็วได้อย่างไร ฉันแสดงหมายเลขนี้ดังนี้:

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: "%.1f", distanceFloat) + "Km"

คำตอบ:


140

สวิฟต์ 3/4:

var distanceFloat1: Float = 5.0
var distanceFloat2: Float = 5.540
var distanceFloat3: Float = 5.03

extension Float {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

print("Value \(distanceFloat1.clean)") // 5
print("Value \(distanceFloat2.clean)") // 5.54
print("Value \(distanceFloat3.clean)") // 5.03

Swift 2 (คำตอบเดิม)

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: distanceFloat == floor(distanceFloat) ? “%.0f" : "%.1f", distanceFloat) + "Km"

หรือเป็นส่วนขยาย:

extension Float {
    var clean: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

ฉันเพิ่มบรรทัดนี้ก่อนหน้านี้distanceFloat = floor(distanceFloat * 10) / 10แล้วมันก็ทำงานได้อย่างสมบูรณ์ขอบคุณ :)
Kali Aney

1
สำหรับ Double ส่วนขยาย Double {var clean: String {return self% 1 == 0? String (format: "% .0d", self): String (self)}}
Abo3atef

3
สิ่งนี้จะใช้ไม่ได้ถ้าลูกลอยเป็น 3.01
chengsam

แล้วตัวเลขติดลบล่ะ?
Happiehappie

ใช้ไม่ได้กับหมายเลข 123456738.0 นี้หมายเลขที่แปลงมาเป็น 123456736
Anirudha Mahale

120

ใช้ NSNumberFormatter:

let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2

// Avoid not getting a zero on numbers lower than 1
// Eg: .5, .67, etc...
formatter.numberStyle = .decimal

let nums = [3.0, 5.1, 7.21, 9.311, 600.0, 0.5677, 0.6988]

for num in nums {
    print(formatter.string(from: num as NSNumber) ?? "n/a")
}

ผลตอบแทน:

3

5.1

7.21

9.31

600

0.57

0.7


2
สมบูรณ์แบบ! สิ่งนี้จะต้องอยู่ด้านบน
GoodSp33d

6
สำหรับ Swift 3: let formatter = NumberFormatter() formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 1 statLabel.text = formatter.string(from: value as NSNumber) ?? "n/a"
alexxjk

1
ประมาณ 0.3000 ลองได้. 3; ฉันกำหนดรูปแบบformatter.numberStyle = .decimal
stan liu

@stanliu ถูกต้องถ้าคุณไม่เพิ่ม.decimalnumberStyle ตัวเลขด้านล่าง 1 จะแสดงโดยไม่มีศูนย์ เช่น: .5, .78 ฯลฯ ... กำลังแก้ไขคำตอบทันที
HotFudgeSunday

ฉันเชื่อว่านี่คือสิ่งที่ Apple ตั้งใจจะแก้ปัญหาดังกล่าว
DragonCherry

55

extension เป็นวิธีที่มีประสิทธิภาพในการทำ

ส่วนขยาย :

รหัสสำหรับ Swift 2 (ไม่ใช่ Swift 3 หรือใหม่กว่า):

extension Float {
    var cleanValue: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

การใช้งาน :

var sampleValue: Float = 3.234
print(sampleValue.cleanValue)

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


สนามเด็กเล่นไฟล์ตัวอย่างที่นี่


1
แต่ 3.230000 -> 3.230000 ... แล้ว "-> 3.23" ล่ะ?
CHiP-love-NY

1
@ CHiP-love-NY ฉันไม่เข้าใจเธอ
Ashok

1
ฉันเชื่อว่าเขาคิดว่าส่วนขยายของคุณไม่ได้ลบเลขศูนย์ต่อท้าย แต่ทำได้ สตริง (3.230000) = "3.23"
jeffjv

34

อัปเดตคำตอบที่ยอมรับสำหรับ swift 3 :

extension Float
{
    var cleanValue: String
    {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

การใช้งานจะเป็น:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

ไม่ทำงานเมื่อคุณใส่ ie 14.000005 เปลี่ยนเป็น 14.0
Vetuka

@ sc13 อืมมันแปลกถ้าคุณดันออกไปที่ 14.00000005 เมื่อถึงจุดที่ลูกลอยกลับมา 14 โดยไม่มี 'cleanValue' คิดว่าสิ่งนี้มีส่วนเกี่ยวข้องกับวิธีการจัดการ Float ที่รวดเร็ว จะไปดูว่าฉันสามารถแก้ไขจุดบกพร่องนั้นได้หรือไม่
Christopher Larsen

2
ฉันได้ผลลัพธ์ที่ถูกต้องสำหรับ 14.000005 ดังนั้นความคิดเห็น @ sc13 ดูเหมือนล้าสมัยหรือไม่ถูกต้อง
Cœur

12

ในการจัดรูปแบบเป็น String ให้ทำตามรูปแบบนี้

let aFloat: Float = 1.123

let aString: String = String(format: "%.0f", aFloat) // "1"
let aString: String = String(format: "%.1f", aFloat) // "1.1"
let aString: String = String(format: "%.2f", aFloat) // "1.12"
let aString: String = String(format: "%.3f", aFloat) // "1.123"

หากต้องการส่งเป็น Int ให้ทำตามรูปแบบนี้

let aInt: Int = Int(aFloat) // "1"

เมื่อคุณใช้String(format:initializer Swift จะปัดเศษตัวเลขสุดท้ายตามต้องการโดยอัตโนมัติตามตัวเลขต่อไปนี้


9

คุณสามารถใช้ส่วนขยายตามที่กล่าวไว้แล้ววิธีนี้สั้นกว่าเล็กน้อย:

extension Float {
    var shortValue: String {
        return String(format: "%g", self)
    }
}

ตัวอย่างการใช้งาน:

var sample: Float = 3.234
print(sample.shortValue)

1
จะล้มเหลวสำหรับ0.00000001. ดูเอกสารของ% g ที่pubs.opengroup.org/onlinepubs/009695399/functions/printf.html : " รูปแบบที่ใช้ขึ้นอยู่กับค่าที่แปลงรูปแบบ e (หรือ E) จะใช้เฉพาะในกรณีที่เลขชี้กำลังที่เป็นผลจากการแปลงดังกล่าว น้อยกว่า -4 หรือมากกว่าหรือเท่ากับความแม่นยำ "
Cœur

สมบูรณ์แบบ ขอบคุณ
PhillipJacobs

7

ในSwift 4ให้ลองทำเช่นนี้

    extension CGFloat{
        var cleanValue: String{
            //return String(format: 1 == floor(self) ? "%.0f" : "%.2f", self)
            return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)//
        }
    }

// วิธีใช้ - หากคุณป้อนมากกว่าสองอักขระหลังจุด (.) ระบบจะครอบตัดอักขระสุดท้ายโดยอัตโนมัติและแสดงเพียงสองอักขระหลังจุด

let strValue = "32.12"
print(\(CGFloat(strValue).cleanValue)

จะไม่ตัดเป็นศูนย์จากค่าที่1.1: "1.10"ส่งออกจะ
Cœur

@ Cœurใช้สำหรับแสดงค่าสองค่าหลังจุด (.) หากคุณต้องการแสดงเพียงค่าเดียวให้ใช้ "return self.truncatingRemainder (dividerBy: 1) == 0? string (format:"% .0f ", self): String (format:"% .1f ", self) / / "
Jaydip

ฉันรู้ว่า ... ฉันแค่อธิบายว่าโค้ดของคุณแตกต่างจากพฤติกรรมคำตอบอื่น ๆ อย่างไร
Cœur

4

NSNumberFormatter คือเพื่อนของคุณ

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
let numberFormatter = NSNumberFormatter()
numberFormatter.positiveFormat = "###0.##"
let distance = numberFormatter.stringFromNumber(NSNumber(float: distanceFloat))!
distanceLabel.text = distance + " Km"

4

การจัดรูปแบบด้วยเลขเศษส่วนสูงสุดโดยไม่มีเลขศูนย์ต่อท้าย

สถานการณ์นี้ดีเมื่อต้องการความแม่นยำของเอาต์พุตแบบกำหนดเอง โซลูชันนี้ดูเหมือนเร็วพอ ๆ กับโซลูชัน NumberFormatter + NSNumber จาก MirekEแต่ประโยชน์อย่างหนึ่งก็คือเรากำลังหลีกเลี่ยง NSObject ที่นี่

extension Double {
    func string(maximumFractionDigits: Int = 2) -> String {
        let s = String(format: "%.\(maximumFractionDigits)f", self)
        var offset = -maximumFractionDigits - 1
        for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
            if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
                offset = i
                break
            }
        }
        return String(s[..<s.index(s.endIndex, offsetBy: offset)])
    }
}

(ใช้ได้กับextension Floatแต่ไม่ใช่ประเภท macOS เท่านั้นFloat80)

การใช้งาน: myNumericValue.string(maximumFractionDigits: 2)หรือmyNumericValue.string()

เอาต์พุตสำหรับmaximumFractionDigits: 2:

1.0 → "1"
0.12 → "0.12"
0.012 → "0.01"
0.0012 → "0"
0.00012 → "0"



4

Swift 5 for Double เหมือนกับคำตอบของ @ Frankie สำหรับ float

var dec: Double = 1.0
dec.clean // 1

สำหรับส่วนขยาย

extension Double {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }

}

3

นี่คือรหัสฉบับเต็ม

let numberA: Float = 123.456
let numberB: Float = 789.000

func displayNumber(number: Float) {
    if number - Float(Int(number)) == 0 {
        println("\(Int(number))")
    } else {
        println("\(number)")
    }
}

displayNumber(numberA) // console output: 123.456
displayNumber(numberB) // console output: 789

นี่คือบรรทัดเชิงลึกที่สำคัญที่สุด

func displayNumber(number: Float) {
  1. Int(number)แถบลอยของตัวเลขทศนิยมกับ
  2. Float(Int(number))ส่งกลับจำนวนกลับมาปล้นไปลอยที่จะทำดำเนินการกับ
  3. รับค่าทศนิยมด้วย number - Float(Int(number))
  4. ตรวจสอบว่าค่าตัวเลขทศนิยมว่างเปล่าด้วย if number - Float(Int(number)) == 0

เนื้อหาภายในคำสั่ง if และ else ไม่จำเป็นต้องอธิบาย


ในกรณีของคุณที่คุณต้องการที่จะทำให้ผลตอบแทนจากฟังก์ชั่นStringและแทนการทำprintln(result) return resultฉันหวังว่านี่จะช่วยได้!
Fine Man

2

ซึ่งอาจเป็นประโยชน์เช่นกัน

extension Float {
    func cleanValue() -> String {
        let intValue = Int(self)
        if self == 0 {return "0"}
        if self / Float (intValue) == 1 { return "\(intValue)" }
        return "\(self)"
    }
}

การใช้งาน:

let number:Float = 45.23230000
number.cleanValue()

-1

อาจstringByReplacingOccurrencesOfStringจะช่วยคุณได้ :)

let aFloat: Float = 1.000

let aString: String = String(format: "%.1f", aFloat) // "1.0"

let wantedString: String = aString.stringByReplacingOccurrencesOfString(".0", withString: "") // "1"

สิ่งนี้จะทำลายค่าเช่น 1.05 -> 15
Starceaker

@Starceaker ไม่1.05ดำเนินการString(format: "%.1f", aFloat)ก่อนจะได้1.0ผล หาก1.05ดำเนินการString(format: "%.2f", aFloat)จะเป็น1.05และมากกว่าที่ควรทำstringByReplacingOccurrencesOfString(".00"...)
ลีโอ

ถูกต้องฉันเน้นที่บรรทัดสุดท้าย ฉันคิดว่าคุณแนะนำวิธีแก้ปัญหาหลายอย่าง แต่จริงๆแล้วสายของคุณเชื่อมต่อกัน ความผิดฉันเอง.
Starceaker

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