Swift - Ondalık 0'a eşitse, kayan noktadan ondalık nasıl kaldırılır?


90

Bir ondalıklı bir mesafe görüntülüyorum ve 0'a eşit olması durumunda bu ondalık sayıyı kaldırmak istiyorum (ör: 1200.0Km), bunu hızlı bir şekilde nasıl yapabilirim? Bu numarayı şöyle gösteriyorum:

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

1
Muhtemel Swift
— Çiftten

Yanıtlar:


140

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 (Orijinal cevap)

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

Veya bir uzantı olarak:

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

Bu satırı daha önce ekledim distanceFloat = floor(distanceFloat * 10) / 10ve sonra mükemmel çalıştı, teşekkürler :)
— Kali Aney

1
Double için, uzantı Double {var clean: String {return self% 1 == 0? Dize (biçim: "% .0d", öz): Dize (öz)}}
— Abo3atef

3
Şamandıra 3.01 gibi bir şeyse bu işe yaramayacaktır.
— chengsam

Negatif sayılar ne olacak?
— Happiehappie

Bu 123456738.0 numarası için çalışmaz, dönüştürülen numara 123456736 olarak gelir
— Anirudha Mahale

120

NSNumberFormatter kullanın:

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

İadeler:

3

5.1

7.21

9.31

600

0.57

0.7


2
mükemmel ! Bunun en üstte olması gerekiyor
— GoodSp33d

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

1
0.3000'e ne dersiniz, bunu 0,3 almayı deniyorum; Tarzını belirledimformatter.numberStyle = .decimal
— stan liu

@stanliu doğrudur, eğer .decimal1'in altındaki numberStyle sayılarını eklemezseniz sıfır olmadan görüntülenecektir. Örneğin: .5, .78, vb ... Cevap şimdi düzenleniyor.
— HotFudgeSunday

Apple'ın böyle bir sorunu çözme niyetinin bu olduğuna inanıyorum.
— DragonCherry

55

extension bunu yapmanın güçlü yolu.

Uzantı :

Swift 2 için Kod (Swift 3 veya daha yenisi değil):

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

Kullanım :

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

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


Örnek Playground dosyası burada .


1
Ama 3.230000 -> 3.230000 ... peki ya "-> 3.23"?
— CHiP-love-NY

1
@ CHiP-love-NY, seni anlamadım.
— Ashok

1
Uzantınızın sondaki sıfırları kaldırmadığını düşündüğüne inanıyorum ama kaldırıyor. Dize (3.230000) = "3.23"
— jeffjv

34

Swift 3 için kabul edilen yanıtın güncellenmesi :

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

kullanım şöyle olacaktır:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

İe koyduğunuzda çalışmıyor. 14.000005, 14.0
— Vetuka

@ sc13 Huh, bu garip, eğer onu 14.00000005'e iterseniz, bu noktada şamandıranın kendisi 'cleanValue' olmadan 14'ü döndürür. Bunun Float'u nasıl hızlı kullandığıyla ilgisi olduğunu düşünün. Bakalım bu hatayı düzeltebilecek miyim?
— Christopher Larsen

2
14.000005 için doğru çıktıyı alıyorum, bu nedenle @ sc13 yorumu eski veya yanlış görünüyor.
— Cœur

12

Dize olarak biçimlendirmek için bu kalıbı izleyin

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'e çevirmek için bu kalıbı izleyin

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

String(format:Başlatıcıyı kullandığınızda , Swift aşağıdaki sayıya göre gerektiğinde son basamağı otomatik olarak yuvarlar.


9

Daha önce de belirtildiği gibi bir uzantı kullanabilirsiniz, ancak bu çözüm biraz daha kısadır:

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

Örnek kullanım:

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

1
Başarısız olacak 0.00000001. Pubs.opengroup.org/onlinepubs/009695399/functions/printf.html adresindeki% g belgelerine bakın : " Kullanılan stil dönüştürülen değere bağlıdır; stil e (veya E) yalnızca böyle bir dönüşümden kaynaklanan üs kullanılırsa kullanılacaktır. -4'ten küçük veya hassasiyete eşit veya ondan büyük. "
— Cœur

mükemmel. Teşekkürler
— PhillipJacobs

7

In Swift 4 bunu deneyin.

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

// Nasıl kullanılır - (.) Noktasından sonra ikiden fazla karakter girerseniz, son karakter otomatik olarak kırpılır ve noktadan sonra yalnızca iki karakter görüntülenir.

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

Sıfırı değerden kırpmayacaktır 1.1: çıktı olacaktır "1.10".
— Cœur

@ Cœur, (.) Noktasından sonra iki değer görüntülemek için kullanılır. yalnızca bir değeri görüntülemek istiyorsanız, "return self.truncatingRemainder (bölmeBy: 1) == 0? Dize (biçim:"% .0f ", öz): Dize (biçim:"% .1f ", öz) / / "
— Jaydip

Biliyorum ... Kodunuzun diğer bazı cevaplardan nasıl farklı olduğunu anlatıyordum.
— Cœur

4

NSNumberFormatter senin arkadaşı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

Sonunda sıfırlar olmadan maksimum kesir basamaklarıyla biçimlendirme

Bu senaryo, özel bir çıktı hassasiyeti istendiğinde iyidir. Bu çözüm, kabaca MirekE'nin NumberFormatter + NSNumber çözümü kadar hızlı görünüyor , ancak bir yararı burada NSObject'ten kaçınmamız olabilir.

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

(aynı zamanda çalışır extension Float, ancak yalnızca macOS tipi ile çalışmaz Float80)

Kullanım: myNumericValue.string(maximumFractionDigits: 2)veyamyNumericValue.string()

Çıktı maximumFractionDigits: 2:

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



4

Double için Swift 5, @ Frankie'nin float cevabı ile aynı

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

uzantı için

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

}

3

İşte tam kod.

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

İşte derinlemesine en önemli satır.

func displayNumber(number: Float) {
  1. Şamandıranın ondalık basamaklarını çıkarır Int(number) .
  2. Sıyrılmış sayıyı şamandıraya geri döndürür. Float(Int(number)) .
  3. Ondalık basamak değerini alır number - Float(Int(number))
  4. Ondalık basamak değerinin boş olup olmadığını kontrol eder if number - Float(Int(number)) == 0

İf ve else ifadelerindeki içeriklerin açıklanmasına gerek yoktur.


Sizin durumunuzda, işlevin do Stringyerine geri dönmesini istersiniz . Umarım bu yardımcı olur! println(result)return result
— Fine Man

2

Bu da yardımcı olabilir.

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

Kullanım:

let number:Float = 45.23230000
number.cleanValue()

-1

Belki stringByReplacingOccurrencesOfStringsana yardımcı olabilir :)

let aFloat: Float = 1.000

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

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

Bu, 1.05 -> 15
— Starceaker

@Starceaker Hayır, önce 1.05icra String(format: "%.1f", aFloat)edilecek 1.0, işler. eğer 1.05icra String(format: "%.2f", aFloat)edilecekse 1.05ve bunu yapması gereksestringByReplacingOccurrencesOfString(".00"...)
— Aslan

Doğru, son satıra odaklandım. Birkaç çözüm önerdiğini sanıyordum ama aslında hatların bağlantılı. Benim hatam.
— Starceaker

O hiçbir şeydir :)
— Leo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.