Swift - Wie entferne ich eine Dezimalstelle aus einem Gleitkommawert, wenn die Dezimalstelle gleich 0 ist?


85

Ich zeige einen Abstand mit einer Dezimalstelle an und möchte diese Dezimalstelle entfernen, falls sie gleich 0 ist (z. B. 1200,0 km). Wie kann ich das schnell tun? Ich zeige diese Nummer folgendermaßen an:

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

Antworten:


130

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 (Originalantwort)

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

Oder als Erweiterung:

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

Ich habe diese Zeile schon einmal hinzugefügt distanceFloat = floor(distanceFloat * 10) / 10und dann hat es perfekt funktioniert, danke :)
Kali Aney

1
Für Double die Erweiterung Double {var clean: String {return self% 1 == 0? String (Format: "% .0d", self): String (self)}}
Abo3atef

3
Dies funktioniert nicht, wenn der Float so etwas wie 3.01 ist.
Chengsam

Was ist mit negativen Zahlen?
Happiehappie

Es funktioniert nicht für diese 123456738.0 Nummer, die konvertierte Nummer kommt als 123456736
Anirudha Mahale

108

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

Kehrt zurück:

3

5.1

7.21

9.31

600

0,57

0,7


2
perfekt ! Dies muss oben sein
GoodSp33d

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

1
Wie wäre es mit 0,3000, ich versuche dies zu bekommen .3; Ich habe seinen Stil festgelegtformatter.numberStyle = .decimal
Stan Liu

@stanliu ist korrekt, wenn Sie die .decimalZahl nicht hinzufügen. Stilzahlen unter 1 werden ohne Null angezeigt. Beispiel: .5, .78 usw. Bearbeiten Sie die Antwort jetzt.
HotFudgeSunday

Ich glaube, das ist es, was Apple vorhat, um ein solches Problem zu lösen.
DragonCherry

55

extension ist der mächtige Weg, es zu tun.

Erweiterung :

Code für Swift 2 (nicht Swift 3 oder neuer):

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

Verwendung :

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

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

3

sampleValue = 3
print(sampleValue.cleanValue)

3


Eine Beispielspielplatzdatei finden Sie hier .


1
Aber 3.230000 -> 3.230000 ... wie wäre es mit "-> 3.23"?
CHiP-love-NY

1
@ CHiP-love-NY, ich habe dich nicht verstanden.
Ashok

1
Ich glaube, er glaubt, dass Ihre Erweiterung keine nachgestellten Nullen entfernt, aber es tut es. String (3.230000) = "3.23"
jeffjv

33

Aktualisierung der akzeptierten Antwort für Swift 3 :

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

Verwendung wäre nur:

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

Funktioniert nicht, wenn Sie dh setzen. 14.000005, konvertiert es zu 14.0
Vetuka

@ sc13 Huh, das ist komisch, wenn du es auf 14.00000005 drückst, an welchem ​​Punkt der Float selbst 14 ohne 'cleanValue' zurückgibt. Ich denke, das hat etwas damit zu tun, wie schnell Float damit umgeht. Ich werde sehen, ob ich diesen Fehler beheben kann.
Christopher Larsen

2
Ich erhalte die richtige Ausgabe für 14.000005, daher scheint der Kommentar zu @ sc13 veraltet oder falsch zu sein.
Cœur

10

Befolgen Sie dieses Muster, um es in String zu formatieren

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"

Folgen Sie diesem Muster, um es in Int umzuwandeln

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

9

Sie können eine Erweiterung verwenden, wie bereits erwähnt. Diese Lösung ist jedoch etwas kürzer:

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

Anwendungsbeispiel:

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

1
Wird scheitern für 0.00000001. Siehe Dokumentation von% g unter pubs.opengroup.org/onlinepubs/009695399/functions/printf.html : " Der verwendete Stil hängt vom konvertierten Wert ab; Stil e (oder E) darf nur verwendet werden, wenn der Exponent aus einer solchen Konvertierung resultiert ist kleiner als -4 oder größer als oder gleich der Genauigkeit. "
Cœur

perfekt. Danke
PhillipJacobs

7

Versuchen Sie dies in Swift 4 .

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

// Verwendung - Wenn Sie nach (.) Punkt mehr als zwei Zeichen eingeben, wird das letzte Zeichen automatisch beschnitten und nur zwei Zeichen nach dem Punkt angezeigt.

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

Trimmt die Null nicht vom Wert ab 1.1: Ausgabe wird sein "1.10".
Cœur

@ Cœur wird verwendet, um zwei Werte nach Punkt (.) Anzuzeigen. Wenn Sie nur einen Wert anzeigen möchten, verwenden Sie "return self.truncatingRemainder (dividingBy: 1) == 0? String (Format:"% .0f ", self): String (Format:"% .1f ", self) / / "
Jaydip

Ich weiß ... Ich habe nur beschrieben, wie sich Ihr Code von anderen Antwortverhalten unterscheidet.
Cœur

4

NSNumberFormatter ist dein Freund

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

Formatierung mit maximalen Bruchstellen ohne nachgestellte Nullen

Dieses Szenario ist gut, wenn eine benutzerdefinierte Ausgabegenauigkeit gewünscht wird. Diese Lösung scheint ungefähr so ​​schnell zu sein wie die NumberFormatter + NSNumber- Lösung von MirekE , aber ein Vorteil könnte sein, dass wir hier NSObject vermeiden.

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

(funktioniert auch mit extension Float, aber nicht mit dem MacOS-Typ Float80)

Verwendung: myNumericValue.string(maximumFractionDigits: 2)odermyNumericValue.string()

Ausgabe für maximumFractionDigits: 2:

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


3

Hier ist der vollständige Code.

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

Hier ist die wichtigste Zeile im Detail.

func displayNumber(number: Float) {
  1. Entfernt die Dezimalstellen des Floats mit Int(number).
  2. Gibt die gestrippte Nummer zurück an float, um eine Operation mit auszuführen Float(Int(number)).
  3. Ruft den Dezimalstellenwert mit ab number - Float(Int(number))
  4. Überprüft, ob der Dezimalstellenwert mit leer ist if number - Float(Int(number)) == 0

Der Inhalt der if- und else-Anweisungen muss nicht erläutert werden.


In Ihrem Fall möchten Sie die Funktion zurückgeben Stringund anstelle von println(result)do return result. Ich hoffe das hilft!
Fine Man


3

Swift 5 für Double ist dasselbe wie @ Frankies Antwort für Float

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

für die Erweiterung

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

}

2

Dies könnte auch hilfreich sein.

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

Verwendung:

let number:Float = 45.23230000
number.cleanValue()

-1

Vielleicht stringByReplacingOccurrencesOfStringkönnte dir helfen :)

let aFloat: Float = 1.000

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

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

Dies würde einen Wert wie 1,05 -> 15
Starceaker

@Starceaker Nein, zuerst 1.05ausführen String(format: "%.1f", aFloat)wird 1.0, funktioniert. wenn 1.05ausführen String(format: "%.2f", aFloat)wird 1.05, und dann sollte dies tunstringByReplacingOccurrencesOfString(".00"...)
Leo

Richtig, ich habe mich auf die letzte Zeile konzentriert. Ich dachte, Sie haben mehrere Lösungen vorgeschlagen, aber tatsächlich sind Ihre Leitungen verbunden. Mein Fehler.
Starceaker

das ist nichts :)
Leo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.