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.