Swift - Làm thế nào để xóa một số thập phân khỏi một số thực nếu số thập phân bằng 0?


88

Tôi đang hiển thị khoảng cách với một số thập phân và tôi muốn xóa số thập phân này trong trường hợp nó bằng 0 (ví dụ: 1200.0Km), làm cách nào tôi có thể thực hiện điều đó nhanh chóng? Tôi đang hiển thị số này như thế này:

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

1
Bản sao có thể xảy ra với Swift - Loại bỏ các Zeros theo dõi khỏi Double
Cœur

Câu trả lời:


137

Swift 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 (Câu trả lời gốc)

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

Hoặc dưới dạng phần mở rộng:

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

Tôi đã thêm dòng này trước distanceFloat = floor(distanceFloat * 10) / 10và sau đó nó đã làm việc một cách hoàn hảo, nhờ :)
Kali Aney

1
Đối với Double, tiện ích mở rộng Double {var clean: String {return self% 1 == 0? Chuỗi (định dạng: "% .0d", tự): Chuỗi (tự)}}
Abo3atef Ngày

3
Điều này sẽ không hoạt động nếu float giống như 3.01.
chengsam

Còn số âm thì sao?
Happiehappie

Nó không làm việc cho số 123.456.738,0 này, số lượng chuyển đổi đến như là 123.456.736
Anirudha Mahale

116

Sử dụng 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")
}

Lợi nhuận:

3

5.1

7.21

9.31

600

0,57

0,7


2
hoàn hảo ! Nhu cầu này phải được trên đầu
GoodSp33d

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

1
Khoảng 0,3000 thì sao, tôi thử cái này được .3; Tôi đặt kiểu của nóformatter.numberStyle = .decimal
stan liu

@stanliu là đúng, nếu bạn không thêm .decimalnumberStyle số dưới 1 sẽ hiển thị không có số 0. Vd: .5, .78, v.v ... Đang chỉnh sửa câu trả lời.
HotFudgeSunday

Tôi tin rằng đây là ý định của Apple để giải quyết vấn đề như vậy.
DragonCherry

55

extension là cách hiệu quả để làm điều đó.

Phần mở rộng :

Mã cho Swift 2 (không phải Swift 3 hoặc mới hơn):

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

Cách sử dụng :

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

3,234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


Tệp sân chơi mẫu ở đây .


1
Nhưng 3.230000 -> 3.230000 ... còn "-> 3.23" thì sao?
CHiP-love-NY

1
@ CHiP-love-NY, tôi không hiểu bạn.
Ashok

1
Tôi tin rằng anh ấy nghĩ rằng tiện ích mở rộng của bạn không xóa các số không ở cuối nhưng nó có. Chuỗi (3.230000) = "3,23"
jeffjv

34

Cập nhật câu trả lời được chấp nhận cho swift 3 :

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

cách sử dụng sẽ chỉ là:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

Không hoạt động khi bạn đặt tức là. 14,000005, nó chuyển đổi thành 14,0
Vetuka

@ sc13 Huh, thật kỳ lạ, nó xảy ra nếu bạn đẩy nó ra 14,00000005 tại thời điểm đó bản thân phao đang trả về 14 mà không có 'cleanValue'. Hãy nghĩ rằng điều này có liên quan đến cách xử lý nhanh chóng của Float. Đi để xem nếu tôi có thể sửa lỗi đó.
Christopher Larsen

2
Tôi nhận được đầu ra chính xác cho 14.000005, vì vậy nhận xét @ sc13 có vẻ như đã lỗi thời hoặc không chính xác.
Cœur

10

Để định dạng nó thành Chuỗi, hãy làm theo mẫu này

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"

Để truyền nó thành Int, hãy làm theo mẫu này

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

Khi bạn sử dụng trình String(format:khởi tạo, Swift sẽ tự động làm tròn chữ số cuối cùng khi cần dựa trên số sau.


Điều này sẽ không hoạt động nếu giá trị là
1.678

@SauravNagpal Nó sẽ hoạt động :)
Baig

9

Bạn có thể sử dụng một tiện ích mở rộng như đã được đề cập, tuy nhiên giải pháp này ngắn hơn một chút:

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

Ví dụ sử dụng:

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

1
Sẽ thất bại cho 0.00000001. Xem tài liệu về% g tại pubs.opengroup.org/onlinepubs/009695399/functions/printf.html : " Kiểu được sử dụng phụ thuộc vào giá trị được chuyển đổi; kiểu e (hoặc E) sẽ chỉ được sử dụng nếu số mũ tạo ra từ chuyển đổi đó nhỏ hơn -4 hoặc lớn hơn hoặc bằng độ chính xác. "
Cœur

hoàn hảo. Cảm ơn
PhillipJacobs

7

Trong Swift 4, hãy thử điều này.

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

// Cách sử dụng - nếu bạn nhập thêm hai ký tự sau dấu (.), Nó sẽ tự động cắt ký tự cuối cùng và chỉ hiển thị hai ký tự sau điểm.

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

Sẽ không cắt số 0 khỏi giá trị 1.1: đầu ra sẽ là "1.10".
Cœur

@ Cœur nó được sử dụng để hiển thị hai giá trị sau dấu (.). nếu bạn chỉ muốn hiển thị một giá trị thì hãy sử dụng "return self.truncatingRemainder (splitBy: 1) == 0? String (format:"% .0f ", self): String (format:"% .1f ", self) / / "
Jaydip

Tôi biết ... Tôi chỉ mô tả cách mã của bạn khác với một số hành vi trả lời khác.
Cœur

4

NSNumberFormatter là bạn của bạn

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

Định dạng với số phân số tối đa, không có số 0 ở cuối

Tình huống này tốt khi mong muốn độ chính xác đầu ra tùy chỉnh. Giải pháp này có vẻ nhanh bằng giải pháp NumberFormatter + NSNumber từ MirekE , nhưng một lợi ích có thể là chúng ta đang tránh NSObject ở đây.

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

(cũng hoạt động với extension Float, nhưng không hoạt động với loại chỉ macOS Float80)

Cách sử dụng: myNumericValue.string(maximumFractionDigits: 2)hoặcmyNumericValue.string()

Đầu ra cho maximumFractionDigits: 2:

1,0 → "1"
0,12 → "0,12"
0,012 → "0,01"
0,0012 → "0"
0,00012 → "0"


4

Swift 5 cho Double nó giống như câu trả lời của @ Frankie cho float

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

cho phần mở rộng

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

}

3

Đây là mã đầy đủ.

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

Đây là dòng quan trọng nhất chuyên sâu.

func displayNumber(number: Float) {
  1. Bỏ các chữ số thập phân của float với Int(number).
  2. Trả lại số bị tước trở lại float để thực hiện một thao tác với Float(Int(number)).
  3. Nhận giá trị chữ số thập phân với number - Float(Int(number))
  4. Kiểm tra giá trị chữ số thập phân trống với if number - Float(Int(number)) == 0

Nội dung bên trong câu lệnh if và else không cần giải thích.


Trong trường hợp của bạn, bạn muốn làm cho hàm trả về Stringvà thay vì println(result)làm như vậy return result. Tôi hi vọng cái này giúp được!
Fine Man

3

Đơn giản :

Int(floor(myFloatValue))

Điều này không phải luôn luôn loại bỏ số thập phân? OP không muốn điều đó.
Rakesha Shastri

2

Điều này cũng có thể hữu ích.

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

Sử dụng:

let number:Float = 45.23230000
number.cleanValue()

-1

Có lẽ stringByReplacingOccurrencesOfStringcó thể giúp bạn :)

let aFloat: Float = 1.000

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

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

Điều này sẽ phá vỡ một giá trị như 1,05 -> 15
Starceaker

@Starceaker Không, 1.05thực thi String(format: "%.1f", aFloat)đầu tiên sẽ được 1.0, hoạt động. nếu 1.05thực thi String(format: "%.2f", aFloat)sẽ được 1.05, và hơn nên làm điều nàystringByReplacingOccurrencesOfString(".00"...)
Leo

Đúng, tôi tập trung vào dòng cuối cùng. Tôi nghĩ rằng bạn đã đề xuất một số giải pháp nhưng thực sự các đường dây của bạn đã được kết nối. Lỗi của tôi.
Starceaker

đó không có gì :)
Leo
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.