Cepat dua kali lipat menjadi string


108

Sebelum saya memperbarui xCode 6, saya tidak memiliki masalah dalam mentransmisikan dobel ke string tetapi sekarang memberi saya kesalahan

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

Ini memberi saya pesan kesalahan "double is not convertible to string". Apakah ada cara lain untuk melakukannya?


5
Mungkin juga berguna untuk mendefinisikannya sepertivar b = "\(a)"
erdekhayser

Jawaban:


211

Itu tidak mentransmisikan, itu membuat string dari nilai dengan format.

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

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

Dengan format yang berbeda:

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

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

Anda juga dapat menghilangkan formatproperti jika tidak diperlukan pemformatan.


1
Bagaimana dengan rangkap dengan bilangan pecahan yang lebih besar? Seperti biarkan a = 2.34934340320 biarkan stringValue = String (format: "% f", a) akan menghasilkan 2.349343
Nico

1
Tampilan dapat dikontrol dengan opsi format printf, lihat: String Format Specifiers dan printf (3) .
zaf

2
Anda hanya perlu mengubah format Anda untuk mengontrol jumlah digit: format:"%.1f" = 1 digit // 1.5; format:"%.5f" = 5 digits // 1.50000
Megaetron

3
Harap perbarui jawaban Anda, di Swift 2.1 yang perlu Anda lakukan String(yourDouble).
Alexandre G.

1
Anda dapat menggunakan let, bukan var. Sekarang tidak perlu memanggilnya beberapa kali.
Oleksandr

81
let double = 1.5 
let string = double.description

perbarui Xcode 7.1 • Swift 2.1:

Sekarang Double juga dapat diubah menjadi String sehingga Anda dapat menggunakannya sesuai keinginan:

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

Swift 3 atau yang lebih baru dapat kita perpanjang LosslessStringConvertibledan membuatnya menjadi generik

Xcode 11.3 • Swift 5.1 atau lebih baru

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

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

Untuk sejumlah digit pecahan yang tetap, kami dapat memperluas FloatingPointprotokol:

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

Jika Anda membutuhkan lebih banyak kontrol atas format angka Anda (digit pecahan minimum dan maksimum dan mode pembulatan) Anda dapat menggunakan 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
apakah ini hack atau cara yang sah untuk melakukannya? apakah itu akan menyebabkan masalah dengan versi ios yang berbeda?
Esqarrouth

2
Tidak, Anda tidak akan mengalami masalah dengan versi iOS yang berbeda. Ini juga berfungsi untuk OSX. BTW inilah yang Anda dapatkan saat melakukan Interpolasi String dengan Double atau Int.
Leo Dabus

Sangat berguna. Anda tidak dapat memformat seperti% f. Dan itu bekerja juga untuk Int jadi Anda punya satu cara untuk melakukannya untuk dua jenis.
Patrik Vaberer

Ini tidak akan bekerja untuk 0,00001, ini menjadi "1e-05" sebagai string.
Alex

Ganti String(format: "%.\(digits)f", self as! CVarArg)denganString(format: "%.*f", digits, self as! CVarArg)
rmaddy

21

Selain jawaban @Zaph, Anda dapat membuat extension:

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

Pemakaian:

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

1
@MaximShoustin OP tidak memiliki cukup perwakilan untuk memberikan suara dan menjawab, 15 diperlukan. Saya juga tidak setuju dengan pembuatan Extension, padahal pernyataan: a.toString()dilihat oleh developer lain pasti ada momen WTF.
zaf

1
@Aph mengapa tidak. Untuk memastikan Anda dapat menambahkan beberapa awalan dan mengubahnya myToString()untuk memastikan bahwa definisi kustomnya. Tetapi seperti dalam bahasa lain, pembuatan prototipe mengarah pada menghindari duplikasi kode dan pemeliharaan yang baik.
Maxim Shoustin

@MaximShoustin pertanyaan pemula: apa perbedaan antara println("output: \(a.toString())")dan println("output: \(a)"). Opsi kedua tidak menyebabkan kesalahan kompilasi. Apakah opsi ini praktik yang buruk?
Alex Guerrero

Apakah ada cara cerdas untuk menulis ekstensi seperti itu ke Double atau FloatingPoint yang akan bekerja pada Double Opsional untuk mengembalikan String kosong?
Kinergy

@KinNyatayourDouble?.toString() ?? ""
Leo Dus

11

Swift 3+: Coba baris kode ini

let num: Double = 1.5

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

9

untuk membuat apapun menjadi string dengan cepat kecuali mungkin nilai enum cukup lakukan apa yang Anda lakukan di metode println ()

sebagai contoh:

var stringOfDBL = "\(myDouble)"


3

Fungsi ini memungkinkan Anda menentukan jumlah tempat desimal yang akan ditampilkan:

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

Pemakaian:

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

Gantikan String(format:"%."+numberOfDecimalPlaces.description+"f", number)denganString(format:"%.*f", numberOfDecimalPlaces, number)
rmaddy

3

Ada banyak jawaban di sini yang menyarankan berbagai teknik. Namun saat menyajikan angka di UI, Anda selalu ingin menggunakan a NumberFormatteragar hasilnya diformat dengan benar, dibulatkan, dan dilokalkan:

let value = 10000.5

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

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

Jika Anda ingin jumlah tempat desimal tetap, misalnya untuk nilai mata uang

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

Tapi keindahan dari pendekatan ini, adalah bahwa itu akan dilokalkan dengan benar, menghasilkan di 10,000.50AS tetapi 10.000,50di Jerman. Lokal yang berbeda memiliki format pilihan yang berbeda untuk angka, dan kita harus membiarkanNumberFormatter menggunakan format yang disukai oleh pengguna akhir saat menyajikan nilai numerik dalam UI.

Tak perlu dikatakan, walaupun NumberFormatterpenting saat menyiapkan representasi string dalam UI, itu tidak boleh digunakan jika menulis nilai numerik sebagai string untuk penyimpanan persisten, antarmuka dengan layanan web, dll.


2
Ini harus ditandai sebagai jawaban yang benar
Asad Khan

2

Dalam 3 cepat:

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

1

Di swift 3 itu sederhana seperti yang diberikan di bawah ini

let stringDouble =  String(describing: double)

3
Ini mengembalikan misalnya "Optional(6.1696108999999995)"untuk saya.
McSullivan D'Ander

0
var b = String(stringInterpolationSegment: a)

Ini berhasil untuk saya. Anda mungkin bisa mencobanya


0

Di Swift 4 jika Anda ingin memodifikasi dan menggunakan Double di UI sebagai "String" textLabel, Anda dapat menambahkan ini di akhir file:

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

}

Dan gunakan seperti ini jika Anda ingin memilikinya dalam label teks:

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

Atau cetak sebagai Int:

print(weatherData.tempCelsius.roundToInt())

0

Saya lebih suka pendekatan NSNumber dan NumberFormatter (di mana perlu), juga u dapat menggunakan ekstensi untuk menghindari kode kembung

extension Double {

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

}

Anda juga bisa membutuhkan pendekatan terbalik

extension String {

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

}

mengapa Anda mengembalikan opsional tetapi menetapkan .nan jika nil? Anda harus melakukan salah satunya. Tidak keduanya. Btw Apa yang salah dengan menggunakan penginisialisasi String? Anda juga dapat membuatnya menjadi LossLessStringConvertibleprotokol perluasan yang lebih umum daripada memperpanjang Double extension LosslessStringConvertible { var string: String { return .init(self) } }
Leo Dabus

U benar mengembalikan Double? Apakah menolak karena saya sudah memeriksanya nihil dan mengembalikan NaN
Giuseppe Mazzilli

0

Cepat 5 : Gunakan kode berikut

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

Gantikan String(format: "%.\(points)f", self)denganString(format: "%.*f", points, self)
rmaddy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.