436 votes

Spécification du format de la chaîne de précision en Swift

Voici comment j'aurais précédemment tronqué un flottant à deux décimales

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

J'ai vérifié les documents et l'eBook mais je n'ai pas réussi à trouver la solution. Merci !

862voto

realityone Points 731

Un moyen simple est :

import Foundation // required for String(format: _, _)

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

9 votes

println(String(format: "a float number: %.5f", 1.0321))

84 votes

Je pense que cette réponse est meilleure que la réponse acceptée. Elle est beaucoup plus proche du style c standard printf sans avoir à écrire des extensions séparées.

9 votes

N'oubliez pas le "import Fondation" en haut du fichier.

305voto

Anton Tcholakov Points 534

La meilleure solution que j'ai trouvée jusqu'à présent, à partir de La réponse de David :

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

Je pense que c'est la solution la plus proche de celle de Swift, en liant les opérations de formatage directement au type de données. Il se peut qu'il existe une bibliothèque intégrée d'opérations de formatage quelque part, ou qu'elle soit bientôt disponible. N'oubliez pas que le langage est encore en version bêta.

85 votes

C'est inutilement compliqué. La réponse de realityone fonctionne et est beaucoup plus concise.

11 votes

Bien sûr, si vous ne l'utilisez qu'une fois. Mais si vous souhaitez disposer d'un plus grand nombre d'options de formatage en utilisant l'interpolation de chaînes de caractères (qui est beaucoup plus lisible), vous pouvez placer toutes les extensions de formatage dans un fichier situé ailleurs et y faire référence tout au long de votre projet. Bien sûr, l'idéal serait qu'Apple fournisse la bibliothèque de formatage.

2 votes

Cette solution ne fonctionnera pas dans Swift 1.2 si le résultat n'est pas converti en String.

131voto

Valentin Points 115

J'ai trouvé String.localizedStringWithFormat de fonctionner assez bien :

Exemple :

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

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

0 votes

La question n'a rien à voir avec la gestion des unités. localizedStringWithFormat est une bonne chose, mais n'a rien à voir avec cela.

0 votes

Je suis d'accord AmitP, cette question a été posée avant que String(format : ..., arguments : ...) ne soit disponible.

74voto

Donn Points 33

La plupart des réponses ici sont valables. Cependant, au cas où vous formateriez souvent le nombre, pensez à étendre la classe Float pour ajouter une méthode qui renvoie une chaîne formatée. Voir l'exemple de code ci-dessous. Celui-ci atteint le même objectif en utilisant un formateur de nombres et une extension.

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

La console affiche :

The velocity is 12.33
The velocity is 12.3

Mise à jour de SWIFT 3.1

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

14 votes

J'aimerais que plus de gens utilisent NSNumberFormatter comme cette réponse. Les autres réponses qui ont reçu un grand nombre de votes ne reflètent simplement pas les paramètres régionaux des appareils (par exemple, dans certaines régions, on utilise une virgule pour la décimale ; cette réponse le reflète ; les autres réponses ne le font pas).

3 votes

La seule amélioration que j'aimerais voir, c'est le stockage du formateur pour un nombre donné - les formateurs NSNumberFormatters sont coûteux à construire.

1 votes

Exactement, ce que je cherchais ! Merci

52voto

David Points 8433

Vous ne pouvez pas (encore) le faire avec l'interpolation de chaînes de caractères. Votre meilleure option reste le formatage NSString :

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

En extrapolant à partir de python, il semble qu'une syntaxe raisonnable pourrait être :

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

Ce qui vous permet ensuite de les utiliser comme :

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

Vous pouvez définir des opérateurs similaires pour tous les types numériques, malheureusement je n'ai pas trouvé le moyen de le faire avec des génériques.

Mise à jour de Swift 5

Depuis au moins Swift 5, String soutient directement le format: il n'est donc pas nécessaire d'utiliser l'initialisateur NSString y el @infix n'est plus nécessaire, ce qui signifie que les exemples ci-dessus doivent être écrits comme suit :

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

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

Double.pi % "%5.3f"         // "3.142"

0 votes

Où avez-vous trouvé cette syntaxe `NSString(format : "formatString", val)'. Je ne la vois pas dans le document iBooks d'Apple.

1 votes

C'est la même chose que de construire n'importe quel objet objectif-c à partir du martinet. C'est la version swift de [NSString stringWithFormat...

0 votes

Je t'ai eu. Je ne suis pas encore allé aussi loin dans l'iBook Swift.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X