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.