文字列にすばやくダブル


108

xCode 6を更新する前は、doubleを文字列にキャストしても問題ありませんでしたが、エラーが発生します

var a: Double = 1.5
var b: String = String(a)

「doubleは文字列に変換できません」というエラーメッセージが表示されます。それを行う他の方法はありますか?


5
次のように定義することも役立つ場合がありますvar b = "\(a)"
erdekhayser

回答:


211

それはキャストではなく、フォーマットを持つ値から文字列を作成しています。

let a: Double = 1.5
let b: String = String(format: "%f", a)

print("b: \(b)") // b: 1.500000

異なるフォーマットで:

let c: String = String(format: "%.1f", a)

print("c: \(c)") // c: 1.5

format書式設定が不要な場合は、プロパティを省略できます。


1
より大きな小数桁数を持つdoubleはどうですか?let a = 2.34934340320のようにlet stringValue = String(format: "%f"、a)は2.349343
Nico

1
表示は、printfフォーマットオプションで制御できます。文字列フォーマット指定子printf(3)を参照してください。
zaph 2015年

2
桁数を制御するには、フォーマットを変更する必要がありますformat:"%.1f" = 1 digit // 1.5format:"%.5f" = 5 digits // 1.50000
Megaetron、2015

3
回答を更新してください。Swift2.1では実行する必要がありますString(yourDouble)
Alexandre G.

1
varの代わりにletを使用できます。これを数回呼び出す必要はありません。
Oleksandr

81
let double = 1.5 
let string = double.description

Xcode 7.1の更新•Swift 2.1:

これでDoubleもStringに変換できるので、好きなように使用できます。

let double = 1.5
let doubleString = String(double)   // "1.5"

Swift 3以降では、拡張LosslessStringConvertibleして汎用にすることができます

Xcode 11.3•Swift 5.1以降

extension LosslessStringConvertible { 
    var string: String { .init(self) } 
}

let double = 1.5 
let string = double.string  //  "1.5"

固定数の小数桁の場合、FloatingPointプロトコルを拡張できます。

extension FloatingPoint {
    func fixedFraction(digits: Int) -> String {
        return String(format: "%.*f", digits, self as! CVarArg)
    }
}

数値形式(最小および最大の小数桁数と丸めモード)をさらに制御する必要がある場合は、NumberFormatterを使用できます。

extension Formatter {
    static let number = NumberFormatter()
}

extension FloatingPoint {
    func fractionDigits(min: Int = 2, max: Int = 2, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
        Formatter.number.minimumFractionDigits = min
        Formatter.number.maximumFractionDigits = max
        Formatter.number.roundingMode = roundingMode
        Formatter.number.numberStyle = .decimal
        return Formatter.number.string(for: self) ?? ""
    }
}

2.12345.fractionDigits()                                    // "2.12"
2.12345.fractionDigits(min: 3, max: 3, roundingMode: .up)   // "2.124"

1
これはハックですか、それともこれを行う正当な方法ですか?異なるバージョンのiOSで問題が発生しますか?
Esqarrouth 2014

2
いいえ、iOSのバージョンが異なっていても問題はありません。OSXでも動作します。ところで、これは、DoubleまたはIntで文字列補間を行うときに得られるものです。
Leo Dabus 2014

非常に便利。%fのようにフォーマットすることはできません。そして、それはIntでも機能するので、2つのタイプでそれを行う1つの方法があります。
Patrik Vaberer 2015

これは0.00001では機能せず、文字列として「1e-05」になります。
Alex

交換するString(format: "%.\(digits)f", self as! CVarArg)String(format: "%.*f", digits, self as! CVarArg)
rmaddy

21

@Zaphの回答に加えて、以下を作成できます。 extension:

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

使用法:

var a:Double = 1.5
println("output: \(a.toString())")  // output: 1.5

1
@MaximShoustin OPには、賛成票と反対票を投じるのに十分な担当者がいません。15が必要です。エクステンションを作成することにも同意しa.toString()ません。別の開発者がこのステートメントを見ると、WTFの瞬間が必ず発生します。
zaph 2014

1
@Zaphなぜだ。確かに、プレフィックスを追加myToString()して、そのカスタム定義を確実にするように変更できます。しかし、他の言語のように、プロトタイピングはコードの重複や適切なメンテナンスを回避することにつながります。
Maxim Shoustin、2014

初心者の質問@MaximShoustin:違いは何だprintln("output: \(a.toString())")println("output: \(a)")。2番目のオプションでは、コンパイルエラーは発生しません。このオプションは悪い習慣ですか?
Alex Guerrero

空の文字列を返すオプションのDoubleで機能するようなDoubleまたはFloatingPointへの拡張を書くための巧妙な方法はありますか?
Kinergy、

@KinergyyourDouble?.toString() ?? ""
レオDabus

11

Swift 3+:次のコード行を試してください

let num: Double = 1.5

let str = String(format: "%.2f", num)

9

enum値以外の文字列を迅速に文字列にするには、単にprintln()メソッドで行うことを実行します

例えば:

var stringOfDBL = "\(myDouble)"


3

この関数では、表示する小数点以下の桁数を指定できます。

func doubleToString(number:Double, numberOfDecimalPlaces:Int) -> String {
    return String(format:"%."+numberOfDecimalPlaces.description+"f", number)
}

使用法:

let numberString = doubleToStringDecimalPlacesWithDouble(number: x, numberOfDecimalPlaces: 2)

交換するString(format:"%."+numberOfDecimalPlaces.description+"f", number)String(format:"%.*f", numberOfDecimalPlaces, number)
rmaddy

3

ここには、さまざまな手法を提案する多くの答えがあります。ただし、UIで数値を表示するときは、必ずを使用しNumberFormatterて、結果が適切にフォーマットされ、丸められ、ローカライズされるようにします。

let value = 10000.5

let formatter = NumberFormatter()
formatter.numberStyle = .decimal

guard let string = formatter.string(for: value) else { return }
print(string) // 10,000.5

小数点以下の桁数を固定したい場合(通貨値など)

let value = 10000.5

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

guard let string = formatter.string(for: value) else { return }
print(string) // 10,000.50

しかし、このアプローチの優れた点は、適切にローカライズされ、その結果10,000.50、米国で10.000,50はドイツになるということです。ロケールによって、数値の優先フォーマットが異なりますNumberFormatter。UIで数値を表示する場合は、エンドユーザーが優先するフォーマットを使用する必要があります。

言うまでもなくNumberFormatter、UI内で文字列表現を準備する際に不可欠ですが、永続ストレージ、Webサービスとのインターフェースなどの文字列として数値を書き込む場合は使用しないでください。


2
これは正解としてマークする必要があります
アサドカーン



0
var b = String(stringInterpolationSegment: a)

これは私にとってはうまくいきます。あなたは試してみるかもしれません


0

Swift 4では、UIでDoubleを変更してtextLabel "String"として使用する場合は、これをファイルの最後に追加できます。

    extension Double {
func roundToInt() -> Int{
    return Int(Darwin.round(self))
}

}

テキストラベルに入れたい場合は、次のように使用します。

currentTemp.text = "\(weatherData.tempCelsius.roundToInt())"

または、Intとして印刷します。

print(weatherData.tempCelsius.roundToInt())

0

私はNSNumberおよびNumberFormatterアプローチ(必要な場合)を好みます。また、拡張機能を使用してコードの肥大化を回避できます。

extension Double {

   var toString: String {
      return NSNumber(value: self).stringValue
   }

}

Uは逆のアプローチも必要です

extension String {

    var toDouble: Double {
        return Double(self) ?? .nan
    }

}

なぜオプションを返しますが、nilの場合は.nanを割り当てるのですか?どちらかを行う必要があります。両方ではありません。ところで、文字列イニシャライザの使用の何が問題になっていますか?LossLessStringConvertibleダブルを拡張する代わりに、より一般的な拡張プロトコルにすることもできます extension LosslessStringConvertible { var string: String { return .init(self) } }
Leo Dabus

UはDoubleを正しく返していますか?私はすでにそれがnilであることを確認してNaNを返すので、拒否で​​す
Giuseppe Mazzilli

0

Swift 5:次のコードを使用

extension Double {

    func getStringValue(withFloatingPoints points: Int = 0) -> String {
        let valDouble = modf(self)
        let fractionalVal = (valDouble.1)
        if fractionalVal > 0 {
            return String(format: "%.*f", points, self)
        }
        return String(format: "%.0f", self)
    }
}

交換するString(format: "%.\(points)f", self)String(format: "%.*f", points, self)
rmaddy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.