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"
Kali Aney
sumber
1
Kemungkinan duplikat Swift - Hapus Trailing Zero Dari Double
Cœur

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)
    }
}
Frankie
sumber
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

MirekE
sumber
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 .

Ashok
sumber
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
Christopher Larsen
sumber
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.

Baig
sumber
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)
Linus
sumber
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)
Jaydip
sumber
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"
vadian
sumber
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"

Cœur
sumber
4

Sederhana:

Int(floor(myFloatValue))
ergunkocak
sumber
Bukankah ini selalu menghapus desimal? OP tidak menginginkan itu.
Rakesha Shastri
jawaban yang sangat sederhana.
caesss
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)
    }

}
Mohamed Shaban
sumber
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.

Baik
sumber
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()
Santosh Maharjan
sumber
-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"
Leo
sumber
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