Dize hızlı çift


108

XCode 6'yı güncellemeden önce, bir dizeye çift atarken hiçbir sorun yaşamadım ama şimdi bana bir hata veriyor

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

Bana "çift dizeye dönüştürülemez" hata mesajını veriyor. Bunu yapmanın başka bir yolu var mı?


5
Bunu şöyle tanımlamak da yararlı olabilirvar b = "\(a)"
— erdekhayser

Yanıtlar:


211

Çevrim değil, formatlı bir değerden bir string yaratıyor.

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

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

Farklı bir formatla:

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

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

formatBiçimlendirme gerekmiyorsa özelliği atlayabilirsiniz .


1
Kesir sayıları daha büyük olan bir ikiye ne dersiniz? Let a = 2.34934340320 gibi let stringValue = String (format: "% f", a) 2.349343
— Nico

1
Görüntü, printf formatlama seçenekleriyle kontrol edilebilir, bakınız: String Format Specifiers ve printf (3) .
— zaph

2
Basamak miktarını kontrol etmek için formatınızı değiştirmeniz yeterlidir format:"%.1f" = 1 digit // 1.5:; format:"%.5f" = 5 digits // 1.50000
— Megaetron

3
Lütfen cevabınızı güncelleyin, Swift 2.1'de yapmanız gereken tek şey String(yourDouble).
— Alexandre G.

1
Var yerine let'i kullanabilirsiniz. Şimdi birkaç kez aramanıza gerek yok.
— Oleksandr

81
let double = 1.5 
let string = double.description

Xcode 7.1'i güncelleyin • Swift 2.1:

Artık Double, String'e dönüştürülebilir, böylece istediğiniz gibi kullanabilirsiniz:

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

Swift 3 veya daha sonra genişletebilir LosslessStringConvertibleve genel hale getirebiliriz

Xcode 11.3 • Swift 5.1 veya üzeri

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

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

Sabit sayıda kesir basamağı için FloatingPointprotokolü genişletebiliriz :

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

Sayı biçiminiz üzerinde daha fazla kontrole ihtiyacınız varsa (minimum ve maksimum kesir basamakları ve yuvarlama modu) NumberFormatter'ı kullanabilirsiniz:

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
bu bir hack mi yoksa bunu yapmanın yasal bir yolu mu? farklı ios sürümlerinde herhangi bir soruna neden olur mu?
— Esqarrouth

2
Hayır, farklı ios sürümleriyle herhangi bir problem yaşamazsınız. OSX için de çalışıyor. BTW, Double veya Int ile String Interpolation yaparken elde ettiğiniz şey budur.
— Leo Dabus

Çok kullanışlı. % F gibi biçimlendiremezsiniz. Ve Int için de işe yarıyor, bu yüzden bunu iki tür için yapmanın bir yolu var.
— Patrik Vaberer

Bu 0.00001 için çalışmaz, dizge olarak "1e-05" olur.
— Alex

Değiştir String(format: "%.\(digits)f", self as! CVarArg)ileString(format: "%.*f", digits, self as! CVarArg)
— rmaddy

21

@Zaph cevabına ek olarak, extension:

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

Kullanımı:

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

1
@MaximShoustin OP'nin oy vermek ve cevaplamak için yeterli repliği yok, 15 gereklidir. Ayrıca bir Uzantı oluşturmaya da katılmıyorum, şu ifade a.toString()başka bir geliştirici tarafından görüldüğünde kesinlikle bir WTF anı olacaktır.
— zaph

1
@Zaph neden olmasın. Elbette, bazı önekler ekleyebilir myToString()ve özel tanımından emin olmak için değiştirebilirsiniz . Ancak diğer dillerde olduğu gibi prototipleme, kod kopyalarının ve iyi bakımın önlenmesine yol açar.
— Maxim Shoustin

@MaximShoustin acemi soru: println("output: \(a.toString())")ve arasındaki fark nedir println("output: \(a)")? İkinci seçenek derleme hatalarına neden olmaz. Bu seçenek kötü bir uygulama mı?
— Alex Guerrero

Double veya FloatingPoint'e böyle bir uzantı yazmanın, bir İsteğe Bağlı Çift üzerinde çalışarak boş bir String döndürmek için akıllıca bir yolu var mı?
— Kinergy

@KinergyyourDouble?.toString() ?? ""
— Leo Dabus

11

Swift 3+: Bu kod satırını deneyin

let num: Double = 1.5

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

9

belki de enum değerleri dışında herhangi bir şeyi bir dizge yapmak için println () yönteminde yaptığınız şeyi yapın

Örneğin:

var stringOfDBL = "\(myDouble)"


3

Bu işlev, gösterilecek ondalık basamak sayısını belirlemenize izin verir:

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

Kullanımı:

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

Değiştir String(format:"%."+numberOfDecimalPlaces.description+"f", number)ileString(format:"%.*f", numberOfDecimalPlaces, number)
— rmaddy

3

Burada çeşitli teknikler öneren birçok cevap var. Ancak, kullanıcı arayüzünde sayıları sunarken NumberFormatter, sonuçların düzgün şekilde biçimlendirilmesi, yuvarlanması ve yerelleştirilmesi için her zaman bir a kullanmak istersiniz :

let value = 10000.5

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

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

Sabit sayıda ondalık basamak istiyorsanız, örneğin para birimi değerleri için

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

Ancak bu yaklaşımın güzelliği, doğru bir şekilde yerelleştirilmesi ve sonuç olarak 10,000.50ABD'de ancak 10.000,50Almanya'da ortaya çıkmasıdır . Farklı yerel ayarların sayılar için farklı tercih edilen biçimleri NumberFormattervardır ve kullanıcı arayüzünde sayısal değerleri sunarken son kullanıcı tarafından tercih edilen biçimi kullanmamıza izin vermeliyiz .

Söylemeye gerek yok NumberFormatter, kullanıcı arayüzü içinde dize gösterimleri hazırlarken çok önemliyken, kalıcı depolama için dizeler olarak sayısal değerler yazarken, web servisleriyle arayüz vb. Yazılıyorsa kullanılmamalıdır.


2
Bu doğru cevap olarak işaretlenmelidir
— Esad Khan

2

Hızlı 3'te:

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

1

Swift 3'te aşağıda verildiği gibi basittir

let stringDouble =  String(describing: double)

3
Bu, örneğin "Optional(6.1696108999999995)"benim için döndürür .
— McSullivan D'Ander

0
var b = String(stringInterpolationSegment: a)

Bu benim için çalışıyor. Bir deneyebilirsin


0

Swift 4'te, kullanıcı arayüzünde bir İkili değiştirmek ve kullanmak isterseniz, bunu bir textLabel "String" olarak dosyanızın sonuna ekleyebilirsiniz:

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

}

Ve bir metin etiketinde olmasını istiyorsanız, bunu şu şekilde kullanın:

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

Veya Int olarak yazdırın:

print(weatherData.tempCelsius.roundToInt())

0

NSNumber ve NumberFormatter yaklaşımını tercih ederim (ihtiyaç duyulduğunda), ayrıca şişkinlik kodunu önlemek için uzantı da kullanabilirsiniz.

extension Double {

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

}

U ayrıca ters yaklaşıma da ihtiyaç duyabilir

extension String {

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

}

neden isteğe bağlı olarak geri dönüyorsunuz ama sıfırsa .nan atıyorsunuz? Ya birini ya da diğerini yapmalısın. İkiside değil. Btw Dize başlatıcıyı kullanmanın neresi yanlış? LossLessStringConvertibleDoubleextension LosslessStringConvertible { var string: String { return .init(self) } }
— Leo Dabus'u

Çifte mi dönüyorsun? Zaten sıfır olduğunu kontrol ettiğimden ve
— NaN'yi

0

Swift 5 : Aşağıdaki kodu kullanın

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

Değiştir String(format: "%.\(points)f", self)ileString(format: "%.*f", points, self)
— rmaddy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.