it-swarm.com.de

Präzisions-String-Formatangabe in Swift

Im Folgenden hätte ich vorher einen Float auf zwei Dezimalstellen gekürzt

NSLog(@" %.02f %.02f %.02f", r, g, b);

Ich habe die Dokumente und das eBook geprüft, konnte es aber nicht herausfinden. Vielen Dank!

351
user3524868

Meine bisher beste Lösung nach Davids Antwort :

import Foundation

extension Int {
    func format(f: String) -> String {
        return String(format: "%\(f)d", self)
    }
}

extension Double {
    func format(f: String) -> String {
        return String(format: "%\(f)f", self)
    }
}

let someInt = 4, someIntFormat = "03"
println("The integer number \(someInt) formatted with \"\(someIntFormat)\" looks like \(someInt.format(someIntFormat))")
// The integer number 4 formatted with "03" looks like 004

let someDouble = 3.14159265359, someDoubleFormat = ".3"
println("The floating point number \(someDouble) formatted with \"\(someDoubleFormat)\" looks like \(someDouble.format(someDoubleFormat))")
// The floating point number 3.14159265359 formatted with ".3" looks like 3.142

Ich denke, dass dies die schnellste Lösung ist, die die Formatierungsvorgänge direkt an den Datentyp bindet. Möglicherweise gibt es irgendwo eine eingebaute Bibliothek mit Formatierungsoperationen, oder sie wird möglicherweise bald veröffentlicht. Beachten Sie, dass sich die Sprache noch in der Beta befindet.

253
Anton Tcholakov

ein einfacher Weg ist:

print(String(format: "hex string: %X", 123456))
print(String(format: "a float number: %.5f", 1.0321))
720
realityone

Ich fand, dass String.localizedStringWithFormat ziemlich gut funktioniert:

Beispiel:

let value: Float = 0.33333
let unit: String = "mph"

yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)
122
Valentin

Dies ist eine sehr schnelle und einfache Weise, die keine komplexe Lösung benötigt.

let duration = String(format: "%.01f", 3.32323242)
// result = 3.3
70
fatihyildizhan

Die meisten Antworten sind gültig. Falls Sie die Zahl jedoch häufig formatieren, sollten Sie die Float-Klasse erweitern, um eine Methode hinzuzufügen, die eine formatierte Zeichenfolge zurückgibt. Siehe Beispielcode unten. Das gleiche Ziel wird durch die Verwendung eines Zahlenformatierers und einer Erweiterung erreicht.

extension Float {
    func string(fractionDigits:Int) -> String {
        let formatter = NSNumberFormatter()
        formatter.minimumFractionDigits = fractionDigits
        formatter.maximumFractionDigits = fractionDigits
        return formatter.stringFromNumber(self) ?? "\(self)"
    }
}

let myVelocity:Float = 12.32982342034

println("The velocity is \(myVelocity.string(2))")
println("The velocity is \(myVelocity.string(1))")

Die Konsole zeigt:

The velocity is 12.33
The velocity is 12.3

Swift 3.1 Update

extension Float {
    func string(fractionDigits:Int) -> String {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = fractionDigits
        formatter.maximumFractionDigits = fractionDigits
        return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }
}
55
Donn

Mit String-Interpolation ist dies (noch) nicht möglich. Ihre beste Wette ist immer noch die NSString-Formatierung:

println(NSString(format:"%.2f", sqrt(2.0)))

Aus Python extrapolierend, scheint es eine sinnvolle Syntax zu sein:

@infix func % (value:Double, format:String) -> String {
    return NSString(format:format, value)
}

Damit können Sie sie dann verwenden als:

M_PI % "%5.3f"                // "3.142"

Sie können ähnliche Operatoren für alle numerischen Typen definieren. Leider habe ich mit Generics keine Möglichkeit gefunden.

31
David Berry
import Foundation

extension CGFloat {
    var string1: String {
        return String(format: "%.1f", self)
    }
    var string2: String {
        return String(format: "%.2f", self)
    }
}

Verwendungszweck

let offset = CGPoint(1.23, 4.56)
print("offset: \(offset.x.string1) x \(offset.y.string1)")
// offset: 1.2 x 4.6
12
neoneye

Warum es so kompliziert machen? Sie können dies stattdessen verwenden:

import UIKit

let PI = 3.14159265359

round( PI ) // 3.0 rounded to the nearest decimal
round( PI * 100 ) / 100 //3.14 rounded to the nearest hundredth
round( PI * 1000 ) / 1000 // 3.142 rounded to the nearest thousandth

Sehen Sie, wie es im Spielplatz funktioniert.

PS: Lösung von: http://rrike.sh/xcode/rounding-various-decimal-places-Swift/

11
Steyn Viljoen

Eine elegantere und allgemeinere Lösung besteht darin, den Ruby/Python-Operator % neu zu schreiben:

// Updated for beta 5
func %(format:String, args:[CVarArgType]) -> String {
    return NSString(format:format, arguments:getVaList(args))
}

"Hello %@, This is pi : %.2f" % ["World", M_PI]
10
Vincent Guerci

Einzelheiten

Xcode 9.3, Swift 4.1

Lösung

import Foundation

extension Numeric {

    private func _precision(number: NSNumber, precision: Int, roundingMode: NumberFormatter.RoundingMode) -> Self? {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = precision
        formatter.roundingMode = roundingMode
        if let formatedNumString = formatter.string(from: number), let formatedNum = formatter.number(from: formatedNumString) {
            return formatedNum as? Self
        }
        return nil

    }

    func precision(_ number: Int, roundingMode: NumberFormatter.RoundingMode = NumberFormatter.RoundingMode.halfUp) -> Self? {

        if let num = self as? NSNumber {
            return _precision(number: num, precision: number, roundingMode: roundingMode)
        }
        if let string = self as? String, let double = Double(string) {
            return _precision(number: NSNumber(value: double), precision: number, roundingMode: roundingMode)
        }
        return nil
    }

}

Verwendungszweck

import UIKit

func showInfo<T: Numeric>(value: T) {
    print("Type: \(type(of: value))")
    print("Original Value: \(value)")
    let value1 = value.precision(3)
    print("value1 = \(value1 != nil ? "\(value1!)" : "nil")")
    let value2 = value.precision(2)
    print("value2 = \(value2 != nil ? "\(value2!)" : "nil")")
    if let value1 = value1, let value2 = value2 {
        print("value1 + value2 = \(value1 + value2)")
    }
    print("")
}

let double: Double = 232.1987654321
let float = Float(double)
let cgfloat = CGFloat(double)

showInfo(value: double)
showInfo(value: float)
showInfo(value: cgfloat)

Ergebnis

 enter image description here

6

Schnell 4

let string = String(format: "%.2f", locale: Locale.current, arguments: 15.123)
5
onmyway133

Sie können NSLog wie in Objective-C auch ohne das @ -Zeichen in Swift verwenden.

NSLog("%.02f %.02f %.02f", r, g, b)

Edit: Nachdem ich seit einiger Zeit mit Swift gearbeitet habe, möchte ich auch diese Variante hinzufügen

    var r=1.2
    var g=1.3
    var b=1.4
    NSLog("\(r) \(g) \(b)")

Ausgabe:

2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4
5
hol
extension Double {
  func formatWithDecimalPlaces(decimalPlaces: Int) -> Double {
     let formattedString = NSString(format: "%.\(decimalPlaces)f", self) as String
     return Double(formattedString)!
     }
 }

 1.3333.formatWithDecimalPlaces(2)
4
Lucas Farah

Die bisherigen Antworten, die die meisten Stimmen erhalten haben, basieren auf NSString-Methoden und erfordern, dass Sie Foundation importieren.

Nachdem Sie dies getan haben, haben Sie noch Zugriff auf NSLog.

Ich denke, die Antwort auf die Frage, ob Sie NSLog in Swift weiter verwenden möchten, lautet einfach:

import Foundation

3
fqdn

weniger Tippweise:

func fprint(format: String, _ args: CVarArgType...) {
    print(NSString(format: format, arguments: getVaList(args)))
}
2
peak
//It will more help, by specify how much decimal Point you want.
let decimalPoint = 2
let floatAmount = 1.10001
let amountValue = String(format: "%0.*f", decimalPoint, floatAmount)
2
Ravi H Malviya

hier eine "reine" Swift-Lösung

 var d = 1.234567
operator infix ~> {}
@infix func ~> (left: Double, right: Int) -> String {
    if right == 0 {
        return "\(Int(left))"
    }
    var k = 1.0
    for i in 1..right+1 {
        k = 10.0 * k
    }
    let n = Double(Int(left*k)) / Double(k)
    return "\(n)"
}
println("\(d~>2)")
println("\(d~>1)")
println("\(d~>0)")
2

Macht der Erweiterung

extension Double {
    var asNumber:String {
        if self >= 0 {
            var formatter = NSNumberFormatter()
            formatter.numberStyle = .NoStyle
            formatter.percentSymbol = ""
            formatter.maximumFractionDigits = 1
            return "\(formatter.stringFromNumber(self)!)"
        }
        return ""
    }
}

let velocity:Float = 12.32982342034

println("The velocity is \(velocity.toNumber)")

Ausgabe: Die Geschwindigkeit ist 12.3

2

Auch mit Rundung:

extension Float
{
    func format(f: String) -> String
    {
        return NSString(format: "%\(f)f", self)
    }
    mutating func roundTo(f: String)
    {
        self = NSString(format: "%\(f)f", self).floatValue
    }
}

extension Double
{
    func format(f: String) -> String
    {
        return NSString(format: "%\(f)f", self)
    }
    mutating func roundTo(f: String)
    {
        self = NSString(format: "%\(f)f", self).doubleValue
    }
}

x = 0.90695652173913
x.roundTo(".2")
println(x) //0.91
1
ChikabuZ

Eine Version des Ruby/Python% -Operators von Vincent Guerci, aktualisiert für Swift 2.1:

func %(format:String, args:[CVarArgType]) -> String {
  return String(format:format, arguments:args)
}

"Hello %@, This is pi : %.2f" % ["World", M_PI]
1
paul king

verwenden Sie die Methode unten

let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)

println(output)
1

Sie können auf diese Weise auch einen Operator erstellen 

operator infix <- {}

func <- (format: String, args:[CVarArg]) -> String {
    return String(format: format, arguments: args)
}

let str = "%d %.1f" <- [1453, 1.123]
1
otello

Viele gute Antworten oben, aber manchmal ist ein Muster geeigneter als die "% .3f" - Art von Gobbledygook. Hier ist mein Take mit einem NumberFormatter in Swift 3.

extension Double {
  func format(_ pattern: String) -> String {
    let formatter = NumberFormatter()
    formatter.format = pattern
    return formatter.string(from: NSNumber(value: self))!
  }    
}

let n1 = 0.350, n2 = 0.355
print(n1.format("0.00#")) // 0.35
print(n2.format("0.00#")) // 0.355

Ich wollte, dass hier immer 2 Dezimalstellen angezeigt werden, die dritte jedoch nur, wenn es nicht Null ist.

1
AlexT

Swift2-Beispiel: Bildschirmbreite eines iOS-Geräts, das den Float formatiert und die Dezimalzahl entfernt

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))

Ich weiß nicht über zwei Dezimalstellen, aber so können Sie Floats mit null Dezimalstellen drucken, also kann ich mir vorstellen, dass dies 2 Stellen, 3 Stellen sein können ... (Anmerkung: Sie müssen müssen konvertiert CGFloat in Double, um an String übergeben zu werden (Format :) oder es wird der Wert Null angezeigt.

func logRect(r: CGRect, _ title: String = "") {
    println(String(format: "[ (%.0f, %.0f), (%.0f, %.0f) ] %@",
        Double(r.Origin.x), Double(r.Origin.y), Double(r.size.width), Double(r.size.height), title))
}
0
clearlight

Was ist mit Erweiterungen für Double- und CGFloat-Typen? 

extension Double {

   func formatted(_ decimalPlaces: Int?) -> String {
      let theDecimalPlaces : Int
      if decimalPlaces != nil {
         theDecimalPlaces = decimalPlaces!
      }
      else {
         theDecimalPlaces = 2
      }
      let theNumberFormatter = NumberFormatter()
      theNumberFormatter.formatterBehavior = .behavior10_4
      theNumberFormatter.minimumIntegerDigits = 1
      theNumberFormatter.minimumFractionDigits = 1
      theNumberFormatter.maximumFractionDigits = theDecimalPlaces
      theNumberFormatter.usesGroupingSeparator = true
      theNumberFormatter.groupingSeparator = " "
      theNumberFormatter.groupingSize = 3

      if let theResult = theNumberFormatter.string(from: NSNumber(value:self)) {
         return theResult
      }
      else {
         return "\(self)"
      }
   }
}

Verwendungszweck: 

let aNumber: Double = 112465848348508.458758344
Swift.print("The number: \(aNumber.formatted(2))")

drucke: 112 465 848 348 508.46

0
M Wilm

Swift 4 Xcode 10 Update

extension Double {
    var asNumber:String {
        if self >= 0 {
            let formatter = NumberFormatter()
            formatter.numberStyle = .none
            formatter.percentSymbol = ""
            formatter.maximumFractionDigits = 2
            return "\(formatter.string(from: NSNumber(value: self)) ?? "")"
        }
        return ""
    }
}
0
Leanid Vouk
@infix func ^(left:Double, right: Int) -> NSNumber {
    let nf = NSNumberFormatter()
    nf.maximumSignificantDigits = Int(right)
    return  nf.numberFromString(nf.stringFromNumber(left))
}


let r = 0.52264
let g = 0.22643
let b = 0.94837

println("this is a color: \(r^3) \(g^3) \(b^3)")

// this is a color: 0.523 0.226 0.948
0
user3778351