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"
Kali Aney
quelle

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

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

Ashok
quelle
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
Christopher Larsen
quelle
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"
Baig
quelle
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)
Linus
quelle
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)
Jaydip
quelle
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"
vadian
quelle
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"

Cœur
quelle
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.

Guter Mann
quelle
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

Einfach:

Int(floor(myFloatValue))
Ergunkocak
quelle
Entfernt dies nicht immer die Dezimalstelle? OP will das nicht.
Rakesha Shastri
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)
    }

}
Mohamed Shaban
quelle
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()
Santosh Maharjan
quelle
-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"
Löwe
quelle
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