Swift - Bagaimana cara menghapus desimal dari float jika desimalnya sama dengan 0?


90

Saya menampilkan jarak dengan satu desimal, dan saya ingin menghapus desimal ini seandainya sama dengan 0 (misal: 1200.0Km), bagaimana saya bisa melakukannya dengan cepat? Saya menampilkan nomor ini seperti ini:

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

Jawaban:


140

Cepat 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 (Jawaban asli)

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

Atau sebagai perpanjangan:

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

Saya menambahkan baris ini sebelumnya distanceFloat = floor(distanceFloat * 10) / 10dan kemudian berfungsi dengan sempurna, terima kasih :)
Kali Aney

1
Untuk Double, ekstensi Double {var clean: String {return self% 1 == 0? String (format: "% .0d", self): String (self)}}
Abo3atef

3
Ini tidak akan bekerja jika floatnya seperti 3.01.
chengsam

Bagaimana dengan angka negatif?
Happiehappie

Tidak berfungsi untuk nomor 123456738.0 ini, nomor yang dikonversi menjadi 123456736
Anirudha Mahale

120

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

Pengembalian:

3

5.1

7.21

9.31

600

0,57

0.7


2
sempurna! Ini harus di atas
GoodSp33d

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

1
Bagaimana dengan 0,3000, saya coba get ini .3; Saya menetapkan gayanyaformatter.numberStyle = .decimal
stan liu

@stanliu benar, jika Anda tidak menambahkan .decimalnumberStyle, angka di bawah 1 akan ditampilkan tanpa nol. Misalnya: .5, .78, dll ... Mengedit jawaban sekarang.
HotFudgeSunday

Saya percaya inilah niat apel untuk menyelesaikan masalah tersebut.
DragonCherry

55

extension adalah cara ampuh untuk melakukannya.

Ekstensi :

Kode untuk Swift 2 (bukan Swift 3 atau yang lebih baru):

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

Penggunaan :

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

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


Contoh file Playground ada di sini .


1
Tapi 3.230000 -> 3.230000 ... bagaimana dengan "-> 3.23"?
CHiP-love-NY

1
@ CHiP-love-NY, saya tidak mengerti.
Ashok

1
Saya yakin menurutnya ekstensi Anda tidak menghapus nol di belakangnya, tetapi ternyata ekstensi tersebut berhasil. String (3.230000) = "3.23"
jeffjv

34

Pembaruan jawaban yang diterima untuk swift 3 :

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

penggunaan hanya akan menjadi:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

Tidak bekerja saat Anda meletakkan mis. 14.000005, diubah menjadi 14.0
Vetuka

@ sc13 Huh, itu aneh, itu terjadi jika Anda mendorongnya ke 14.00000005 di mana titik float itu sendiri mengembalikan 14 tanpa 'cleanValue'. Pikirkan ini ada hubungannya dengan seberapa cepat menangani Float. Akan melihat apakah saya bisa memperbaiki bug itu.
Christopher Larsen

2
Saya mendapatkan hasil yang benar untuk 14.000005, jadi komentar @ sc13 tampaknya usang atau tidak benar.
Cœur

12

Untuk memformatnya menjadi String, ikuti pola ini

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"

Untuk mentransmisikannya ke Int, ikuti pola ini

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

Saat Anda menggunakan String(format:penginisialisasi, Swift akan secara otomatis membulatkan digit terakhir sesuai kebutuhan berdasarkan nomor berikut.


9

Anda dapat menggunakan ekstensi seperti yang telah disebutkan, solusi ini sedikit lebih singkat:

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

Contoh penggunaan:

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

1
Akan gagal untuk 0.00000001. Lihat dokumentasi% g di pubs.opengroup.org/onlinepubs/009695399/functions/printf.html : " Gaya yang digunakan bergantung pada nilai yang dikonversi; gaya e (atau E) harus digunakan hanya jika eksponen dihasilkan dari konversi semacam itu kurang dari -4 atau lebih besar dari atau sama dengan presisi. "
Cœur

sempurna. Terima kasih
PhillipJacobs

7

Di Swift 4 coba ini.

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

// Cara menggunakan - jika Anda memasukkan lebih dari dua karakter setelah titik (.), Itu secara otomatis memotong karakter terakhir dan hanya menampilkan dua karakter setelah titik.

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

Tidak akan memangkas nol dari nilai 1.1: keluaran akan "1.10".
Cœur

@ Cœur ini digunakan untuk menampilkan dua nilai setelah titik (.). jika Anda ingin menampilkan hanya satu nilai maka gunakan "return self.truncatingRemainder (dividingBy: 1) == 0? String (format:"% .0f ", self): String (format:"% .1f ", self) / / "
Jaydip

Saya tahu ... Saya baru saja menjelaskan bagaimana kode Anda berbeda dari beberapa perilaku jawaban lainnya.
Cœur

4

NSNumberFormatter adalah teman Anda

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

Memformat dengan angka pecahan maksimum, tanpa nol di belakangnya

Skenario ini bagus ketika presisi keluaran kustom diinginkan. Solusi ini tampaknya kira-kira secepat solusi NumberFormatter + NSNumber dari MirekE , tetapi satu manfaatnya adalah kami menghindari NSObject di sini.

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

(berfungsi juga dengan extension Float, tetapi bukan jenis khusus macOS Float80)

Penggunaan: myNumericValue.string(maximumFractionDigits: 2)ataumyNumericValue.string()

Output untuk maximumFractionDigits: 2:

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



4

Swift 5 untuk Double itu sama dengan jawaban @ Frankie untuk float

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

untuk ekstensi

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

}

3

Berikut kode lengkapnya.

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

Inilah garis yang paling penting secara mendalam.

func displayNumber(number: Float) {
  1. Mengupas angka desimal pelampung dengan Int(number).
  2. Mengembalikan nomor yang telah dilucuti kembali ke float untuk melakukan operasi Float(Int(number)).
  3. Mendapatkan nilai digit desimal dengan number - Float(Int(number))
  4. Memeriksa nilai digit desimal kosong dengan if number - Float(Int(number)) == 0

Konten dalam pernyataan if dan else tidak perlu dijelaskan.


Dalam kasus Anda, Anda ingin membuat fungsi kembali Stringdan alih-alih println(result)melakukan return result. Saya harap ini membantu!
Pria Baik

2

Ini mungkin bisa membantu juga.

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

Pemakaian:

let number:Float = 45.23230000
number.cleanValue()

-1

Mungkin stringByReplacingOccurrencesOfStringbisa membantu Anda :)

let aFloat: Float = 1.000

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

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

Ini akan mematahkan nilai seperti 1,05 -> 15
Starceaker

@Starceaker Tidak, 1.05eksekusi String(format: "%.1f", aFloat)pertama akan 1.0, berhasil. jika 1.05mengeksekusi String(format: "%.2f", aFloat)akan 1.05, dan daripada harus melakukan inistringByReplacingOccurrencesOfString(".00"...)
Leo

Benar, saya fokus pada baris terakhir. Saya pikir Anda menyarankan beberapa solusi tetapi sebenarnya saluran Anda terhubung. Salahku.
Starceaker

itu bukan apa-apa :)
Leo
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.