Swift - Cara mengonversi String menjadi Double

242

Saya mencoba menulis program BMI dalam bahasa cepat. Dan saya mendapat masalah ini: bagaimana cara mengubah sebuah String menjadi Double?

Di Objective-C, saya bisa melakukan ini:

double myDouble = [myString doubleValue];

Tetapi bagaimana saya bisa mencapai ini dalam bahasa Swift?

Oh ya
sumber
1
Ini telah berubah di Swift 2, lihat jawaban baru menggunakan inisialisasi Double () failable baru: stackoverflow.com/a/32850058/276626
Paul Solt

Jawaban:

205

Swift 4.2+ String to Double

Anda harus menggunakan inisialisasi tipe baru untuk mengkonversi antara tipe String dan numerik (Double, Float, Int). Ini akan mengembalikan jenis Opsional (Gandakan?) Yang akan memiliki nilai yang benar atau nihil jika String bukan angka.

Catatan: Properti nilai ganda NSString tidak disarankan karena mengembalikan 0 jika nilai tidak dapat dikonversi (yaitu: input pengguna buruk).

let lessPrecisePI = Float("3.14")

let morePrecisePI = Double("3.1415926536")
let invalidNumber = Float("alphabet") // nil, not a valid number

Buka bungkus nilai untuk menggunakannya menggunakan if / let

if let cost = Double(textField.text!) {
    print("The user entered a value price of \(cost)")
} else {
    print("Not a valid number: \(textField.text!)")
}

Anda dapat mengonversi angka dan mata uang yang diformat menggunakan NumberFormatterkelas.

let formatter = NumberFormatter()
formatter.locale = Locale.current // USA: Locale(identifier: "en_US")
formatter.numberStyle = .decimal
let number = formatter.number(from: "9,999.99")

Format mata uang

let usLocale = Locale(identifier: "en_US")
let frenchLocale = Locale(identifier: "fr_FR")
let germanLocale = Locale(identifier: "de_DE")
let englishUKLocale = Locale(identifier: "en_GB") // United Kingdom
formatter.numberStyle = .currency

formatter.locale = usLocale
let usCurrency = formatter.number(from: "$9,999.99")

formatter.locale = frenchLocale
let frenchCurrency = formatter.number(from: "9999,99€")
// Note: "9 999,99€" fails with grouping separator
// Note: "9999,99 €" fails with a space before the €

formatter.locale = germanLocale
let germanCurrency = formatter.number(from: "9999,99€")
// Note: "9.999,99€" fails with grouping separator

formatter.locale = englishUKLocale
let englishUKCurrency = formatter.number(from: "£9,999.99")

Baca lebih lanjut di posting blog saya tentang mengkonversi String ke tipe Double (dan mata uang) .

Paul Solt
sumber
2
masalah lain adalah bahwa itu tidak mendukung angka di lokal berbeda selain 1.000,00, jika Anda menggunakan format lain seperti 1 000,00 itu akan memotong 2 desimal pada akhirnya. Setidaknya inilah yang terjadi untuk Objective-C. - Sesuai dokumentasi Apple: (Mereka tidak sadar-lokal) Metode kenyamanan berikut semuanya melewati karakter spasi awal (whitespaceSet) dan mengabaikan karakter trailing. Mereka tidak sadar lokal. NSScanner atau NSNumberFormatter dapat digunakan untuk parsing angka yang lebih kuat dan sadar lokal.
mskw
@ mskw Saya telah menambahkan detail tambahan tentang penggunaan NumberFormatter untuk mengurai mata uang. Dalam kode saya saya akan merangkai beberapa upaya formatter untuk mengkonversi menggunakan sintaks if / let sehingga saya dapat menguraikan kedua angka yang diformat mata uang ($ 1.000,00) atau angka yang diformat (1.000). Anda tidak selalu tahu bagaimana pengguna akan memasukkan angka, sehingga dapat mendukung keduanya ideal dengan sekelompok pernyataan if / let.
Paul Solt
276

Swift 2 Perbarui Ada initializers failable baru yang memungkinkan Anda untuk melakukan hal ini dalam cara yang lebih idiomatik dan aman (banyak jawaban telah mencatat, nilai ganda NSString ini sangat tidak aman karena kembali 0 untuk nilai-nilai non nomor. Ini berarti bahwa doubleValuedari "foo"dan "0"yang sama.)

let myDouble = Double(myString)

Ini mengembalikan opsional, jadi dalam kasus seperti melewati di "foo"mana doubleValueakan mengembalikan 0, intializer yang tersedia akan kembali nil. Anda dapat menggunakan guard, if-let, atau mapuntuk menanganiOptional<Double>

Posting Asli: Anda tidak perlu menggunakan konstruktor NSString seperti saran yang diterima. Anda bisa menjembataninya seperti ini:

(swiftString as NSString).doubleValue
Jarsen
sumber
5
ohai, Jarsen. Salah satu kelemahan dari pendekatan ini adalah bahwa itu tidak akan gagal jika string tersebut bukan ganda yang valid. Sebaliknya Anda hanya akan mendapatkan 0,0. Artinya, hasil - [NSString doubleValue]ini Doubledi cepat menutupi peran Double?( Optional<Double>). Ini berbeda dari fungsi Swift String toInt()yang mengembalikan Int?dan menyatakan dalam dokumen bahwa "" menerima string yang cocok dengan ekspresi reguler "[- +]? [0-9] +" hanya. "
Derrick Hathaway
Ya, menggunakan .toInt()akan lebih baik. Namun, ini lebih merupakan jawaban untuk bagaimana melakukan hal yang persis sama, tetapi di Swift.
Jarsen
Pendekatan ini secara ketat memasangkan Anda ke Foundation, dan kemungkinan tidak akan bekerja pada implementasi Swift non-Apple.
Erik Kerber
5
Di Swift 2.0 ada Double.init?(_ text: String)inisialisasi failable sekarang tersedia.
mixel
3
Ini bukan pendekatan terbaik. Ini akan gagal tergantung pada pemisah desimal. Ini akan baik-baik saja dengan '.' tetapi tidak dengan ','. NSNumberFormatter akan mendukung pemisah desimal yang digunakan di lokalisasi saat ini.
Julian Król
75

Untuk perasaan Swift yang lebih sedikit, gunakan NSFormatter()menghindari casting NSString, dan kembali nilketika string tidak mengandung Doublenilai (mis. "Test" tidak akan kembali 0.0).

let double = NSNumberFormatter().numberFromString(myString)?.doubleValue

Atau, perpanjang Stringtipe Swift :

extension String {
    func toDouble() -> Double? {
        return NumberFormatter().number(from: self)?.doubleValue
    }
}

dan gunakan seperti toInt():

var myString = "4.2"
var myDouble = myString.toDouble()

Ini mengembalikan opsi Double?yang harus dibuka.

Baik dengan membuka paksa:

println("The value is \(myDouble!)") // prints: The value is 4.2

atau dengan pernyataan if let:

if let myDouble = myDouble {
    println("The value is \(myDouble)") // prints: The value is 4.2
}

Pembaruan: Untuk pelokalan, sangat mudah untuk menerapkan lokal ke NSFormatter sebagai berikut:

let formatter = NSNumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "fr_FR")
let double = formatter.numberFromString("100,25")

Akhirnya, Anda dapat menggunakan NSNumberFormatterCurrencyStyleformatter jika Anda bekerja dengan mata uang di mana string berisi simbol mata uang.

RyuX51
sumber
Saya suka gagasan memperluas kelas String untuk aplikasi yang akan menggunakan konversi beberapa tempat. Tapi saya tidak melihat manfaat dari kerumitan memohon NSNumberFormatter, karena para pemain NSString dan menggunakan .doubleValue tampaknya setidaknya sebagai langsung, dan lebih mudah dibaca dan diingat.
clearlight
12
Sebenarnya keuntungan menggunakan NSNumberFormatter () adalah bahwa metode numberFromString: akan mengembalikan nol jika string berisi karakter yang tidak membentuk dobel. Masalah dengan nilai ganda pada NSString adalah bahwa ia akan selalu menghasilkan ganda (0,0 untuk "tes" misalnya) terlepas. Jadi jika Anda berurusan dengan semua jenis string dan Anda ingin menguji apakah string tersebut hanya double, tidak ada karakter tambahan, menggunakan NSNumberFormatter adalah cara yang harus dilakukan.
dirkgroten
4
Ini gagal di Perancis.
Peter K.
1
Ini adalah solusi yang bagus, tetapi hanya menggunakan kode ini tidak akan berfungsi di negara-negara di mana koma digunakan sebagai pemisah (termasuk Perancis sebagai @PeterK. Disebutkan). Saya mencoba menulis komentar dengan solusinya, tetapi terlalu lama sehingga saya harus menjawabnya. Ini dia solusi
Jacob R
53

Opsi lain di sini adalah mengonversikan ini menjadi NSStringdan menggunakan itu:

let string = NSString(string: mySwiftString)
string.doubleValue
Keith Smiley
sumber
13
Saya berharap ada cara yang lebih baik untuk melakukan ini. Bagaimana saya bisa tahu jika parsing gagal, misalnya.
Ryan Hoffman
2
@RyanHoffman Sayangnya kontrak nilai ganda NSString tidak pernah memberikan semua itu. Yang Anda dapatkan hanyalah 0,0 jika string tidak dimulai dengan representasi angka yang valid, HUGE_VAL dan -HUGE_VAL pada overflow / underflow. Jika Anda ingin tahu mengapa parsing gagal, saya percaya Anda perlu melihat ke NSNumberFormatter, yang dirancang untuk menangani konversi angka / string dengan cara yang lebih kuat.
Jarsen
Karena mungkin sulit untuk menemukan jawaban itu, ini dia:(swiftString as NSString).doubleValue
LearnCocos2D
24

Berikut adalah metode ekstensi yang memungkinkan Anda cukup memanggil doubleValue () pada string Swift dan mendapatkan kembali ganda (contoh output yang diutamakan)

println("543.29".doubleValue())
println("543".doubleValue())
println(".29".doubleValue())
println("0.29".doubleValue())

println("-543.29".doubleValue())
println("-543".doubleValue())
println("-.29".doubleValue())
println("-0.29".doubleValue())

//prints
543.29
543.0
0.29
0.29
-543.29
-543.0
-0.29
-0.29

Inilah metode ekstensi:

extension String {
    func doubleValue() -> Double
    {
        let minusAscii: UInt8 = 45
        let dotAscii: UInt8 = 46
        let zeroAscii: UInt8 = 48

        var res = 0.0
        let ascii = self.utf8

        var whole = [Double]()
        var current = ascii.startIndex

        let negative = current != ascii.endIndex && ascii[current] == minusAscii
        if (negative)
        {
            current = current.successor()
        }

        while current != ascii.endIndex && ascii[current] != dotAscii
        {
            whole.append(Double(ascii[current] - zeroAscii))
            current = current.successor()
        }

        //whole number
        var factor: Double = 1
        for var i = countElements(whole) - 1; i >= 0; i--
        {
            res += Double(whole[i]) * factor
            factor *= 10
        }

        //mantissa
        if current != ascii.endIndex
        {
            factor = 0.1
            current = current.successor()
            while current != ascii.endIndex
            {
                res += Double(ascii[current] - zeroAscii) * factor
                factor *= 0.1
                current = current.successor()
           }
        }

        if (negative)
        {
            res *= -1;
        }

        return res
    }
}

Tidak ada pengecekan kesalahan, tetapi Anda bisa menambahkannya jika Anda membutuhkannya.

Millie Smith
sumber
20

Pada Swift 1.1, Anda dapat langsung beralih Stringke const char *parameter.

import Foundation

let str = "123.4567"
let num = atof(str) // -> 123.4567

atof("123.4567fubar") // -> 123.4567

Jika Anda tidak suka usang atof:

strtod("765.4321", nil) // -> 765.4321

Satu peringatan: perilaku konversi berbeda dari NSString.doubleValue.

atofdan strtodterima 0xstring hex yang diawali:

atof("0xffp-2") // -> 63.75
atof("12.3456e+2") // -> 1,234.56
atof("nan") // -> (not a number)
atof("inf") // -> (+infinity)

Jika Anda lebih suka .doubleValueperilaku, kami masih dapat menggunakan CFStringbridging:

let str = "0xff"
atof(str)                      // -> 255.0
strtod(str, nil)               // -> 255.0
CFStringGetDoubleValue(str)    // -> 0.0
(str as NSString).doubleValue  // -> 0.0
rintaro
sumber
Saya penggemar pendekatan ini, bukannya casting untuk NSString.
Sam Soffes
10

Di Swift 2.0 cara terbaik adalah menghindari berpikir seperti pengembang Objective-C. Jadi Anda tidak harus "mengkonversi String ke Double" tetapi Anda harus "menginisialisasi Double dari String". Apple doc di sini: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_

Ini adalah init opsional sehingga Anda dapat menggunakan operator penggabungan nil (??) untuk menetapkan nilai default. Contoh:

let myDouble = Double("1.1") ?? 0.0
Toom
sumber
Double.init?(_ text: String)menjadi tersedia di Swift 2.0. Anda harus menyebutkan ini. Jawaban lain di sini bukan karena orang berpikir seperti pengembang Objective-C tetapi karena penginisialisasi ini tidak tersedia sebelumnya.
mixel
Memang kamu benar. Ini hanya tersedia di Swift 2.0, saya akan menyebutkannya :) Tetapi seperti dalam bahasa lain Anda menginisialisasi suatu jenis dengan yang lain dan seharusnya tidak mengharapkan suatu jenis untuk dapat dikonversi menjadi yang lain. Perdebatan panjang tetapi sebagai pengembang Obj-C, saya memiliki banyak praktik buruk ketika melakukan coding dengan Swift dan ini adalah salah satunya :)
Toom
10

Pada SWIFT 3 , Anda dapat menggunakan:

if let myDouble = NumberFormatter().number(from: yourString)?.doubleValue {
   print("My double: \(myDouble)")
}

Catatan: - Jika string berisi karakter apa pun selain angka numerik atau grup yang sesuai dengan lokal atau pemisah desimal, penguraian akan gagal. - Setiap karakter pemisah ruang mengarah atau tertinggal dalam string diabaikan. Misalnya, string "5", "5", dan "5" semua menghasilkan angka 5.

Diambil dari dokumentasi: https://developer.apple.com/reference/foundation/numberformatter/1408845-number

Jorge Luis Jiménez
sumber
10

Saya belum melihat jawaban yang saya cari. Saya hanya memposting di sini milik saya jika itu dapat membantu siapa pun. Jawaban ini hanya valid jika Anda tidak memerlukan format tertentu .

Cepat 3

extension String {
    var toDouble: Double {
        return Double(self) ?? 0.0
    }
}
TomCobo
sumber
9

Coba ini:

   var myDouble = myString.bridgeToObjectiveC().doubleValue
   println(myDouble)

CATATAN

Dihapus dalam Beta 5. Ini tidak lagi berfungsi?

CW0007007
sumber
1
bridgeToObjectiveC () telah dihapus dalam Xcode 6 Beta 5. Metode Mr Smiley adalah yang tercepat yang saya temukan saat ini
faraquet99
7

Ini berdasarkan jawaban dari @Ryu

Solusinya sangat bagus selama Anda berada di negara di mana titik digunakan sebagai pemisah. Secara default NSNumberFormattermenggunakan perangkat lokal. Oleh karena itu, ini akan gagal di semua negara di mana koma digunakan sebagai pemisah default (termasuk Perancis sebagai @PeterK. Disebutkan) jika nomor menggunakan titik sebagai pemisah (yang biasanya merupakan kasus). Untuk mengatur lokal NSNumberFormatter ini menjadi AS dan karenanya menggunakan titik sebagai pemisah menggantikan garis

return NSNumberFormatter().numberFromString(self)?.doubleValue

dengan

let numberFormatter = NSNumberFormatter()
numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
return numberFormatter.numberFromString(self)?.doubleValue

Karenanya kode lengkap menjadi

extension String {
    func toDouble() -> Double? {
        let numberFormatter = NSNumberFormatter()
        numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        return numberFormatter.numberFromString(self)?.doubleValue
    }
}

Untuk menggunakan ini, telepon saja "Your text goes here".toDouble()

Ini akan mengembalikan opsional Double?

Seperti yang disebutkan @Ryu, Anda dapat memaksa membuka:

println("The value is \(myDouble!)") // prints: The value is 4.2

atau gunakan if letpernyataan:

if let myDouble = myDouble {
    println("The value is \(myDouble)") // prints: The value is 4.2
}
Yakub R
sumber
1
Ini adalah jawaban yang benar. Versi Swift 3 akan menjadi NumberFormatter().number(from: myString)?.doubleValue
nicolas leo
7

SWIFT 4

extension String {
    func toDouble() -> Double? {
        let numberFormatter = NumberFormatter()
        numberFormatter.locale = Locale(identifier: "en_US_POSIX")
        return numberFormatter.number(from: self)?.doubleValue
    }
}
t4nhpt
sumber
6

Cepat 4.0

coba ini

 let str:String = "111.11"
 let tempString = (str as NSString).doubleValue
 print("String:-",tempString)
Vishal Vaghasiya
sumber
6

Swift: 4 dan 5

Mungkin ada dua cara untuk melakukan ini:

  1. String -> Int -> Double:

    let strNumber = "314"
    if let intFromString = Int(strNumber){
        let dobleFromInt = Double(intFromString)
        print(dobleFromInt)
    }
  2. String -> NSString -> Double

    let strNumber1 = "314"
    let NSstringFromString = NSString(string: strNumber1)
    let doubleFromNSString = NSstringFromString.doubleValue
    print(doubleFromNSString)

Gunakan itu sesuai keinginan Anda sesuai dengan kode yang Anda butuhkan.

Abhirajsinh Thakore
sumber
Metode pertama tidak bekerja untuk saya, tetapi metode kedua bekerja dengan cukup baik.
Saurabh
@Saurabh, Bisakah Anda menjelaskan lebih lanjut tentang Apa string Anda?
Abhirajsinh Thakore
5

Silakan periksa di taman bermain!

let sString = "236.86"

var dNumber = NSNumberFormatter().numberFromString(sString)
var nDouble = dNumber!
var eNumber = Double(nDouble) * 3.7

Ngomong-ngomong di Xcode saya

.toDouble () - tidak ada

.doubleValue membuat nilai 0,0 dari string bukan numerik ...

Mamazur
sumber
4

1.

let strswift = "12"
let double = (strswift as NSString).doubleValue

2.

var strswift= "10.6"
var double : Double = NSString(string: strswift).doubleValue 

Semoga ini bisa membantu Anda.

Daxesh Nagar
sumber
4

Seperti yang telah ditunjukkan, cara terbaik untuk mencapai ini adalah dengan casting langsung:

(myString as NSString).doubleValue

Membangun dari itu, Anda dapat membuat ekstensi Swift String asli apik:

extension String {
    var doubleValue: Double {
        return (self as NSString).doubleValue
    }
}

Ini memungkinkan Anda untuk langsung menggunakan:

myString.doubleValue

Yang akan melakukan casting untuk Anda. Jika Apple tidak menambahkan doubleValueke String asli Anda hanya perlu menghapus ekstensi dan sisa kode Anda akan secara otomatis dikompilasi dengan baik!

Firo
sumber
Metode Apple akan disebut .toDouble ... sama seperti toInt. Ini kelalaian yang aneh. Kemungkinan akan diperbaiki di versi Swift yang akan datang. Saya suka metode ekstensi yang terbaik, menjaga kode tetap bersih.
n13
Nilai kembalian harus berupa BUKAN Float
Leo Dabus
4

SWIFT 3

Untuk menghapus, saat ini ada metode default:

public init?(_ text: String) dari Double kelas.

Ini dapat digunakan untuk semua kelas.

let c = Double("-1.0") let f = Double("0x1c.6") let i = Double("inf") , dll.

Vyacheslav
sumber
2

Ekstensi dengan lokal opsional

Cepat 2.2

extension String {
    func toDouble(locale: NSLocale? = nil) -> Double? {
        let formatter = NSNumberFormatter()
        if let locale = locale {
            formatter.locale = locale
        }
        return formatter.numberFromString(self)?.doubleValue
    }
}

Cepat 3.1

extension String {
    func toDouble(_ locale: Locale) -> Double {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.locale = locale
        formatter.usesGroupingSeparator = true
        if let result = formatter.number(from: self)?.doubleValue {
            return result
        } else {
            return 0
        }
    }
}
sama
sumber
1
Saya telah menambahkan contoh Swift 3.1. Apa yang Anda maksud dengan "... dan tambahkan contoh untuk lokal"? 🙂
mirip
1

Atau Anda bisa melakukannya:

var myDouble = Double((mySwiftString.text as NSString).doubleValue)
jr00n
sumber
1

Anda dapat menggunakan StringEx . Itu meluas Stringdengan konversi string-ke-nomor termasuk toDouble().

extension String {
    func toDouble() -> Double?
}

Ini memverifikasi string dan gagal jika tidak dapat dikonversi menjadi dua kali lipat.

Contoh:

import StringEx

let str = "123.45678"
if let num = str.toDouble() {
    println("Number: \(num)")
} else {
    println("Invalid string")
}
Stas
sumber
1

Cepat 4

extension String {
    func toDouble() -> Double {
        let nsString = self as NSString
        return nsString.doubleValue
    }
}
Aitor Lucas
sumber
0

Apa yang juga berfungsi:

// Init default Double variable
var scanned: Double()

let scanner = NSScanner(string: "String to Scan")
scanner.scanDouble(&scanned)

// scanned has now the scanned value if something was found.
Bijan
sumber
CATATAN: 'scanDouble' sudah tidak digunakan lagi di iOS 13.0
uplearnedu.com
0

Gunakan kode ini di Swift 2.0

let strWithFloat = "78.65" let floatFromString = Double(strWithFloat)

Maninderjit Singh
sumber
0

Menggunakan Scannerdalam beberapa kasus adalah cara yang sangat mudah untuk mengekstraksi angka dari string. Dan itu hampir sama kuatnya dengan NumberFormatterketika memecahkan kode dan menangani berbagai format angka dan lokal. Ini dapat mengekstraksi angka dan mata uang dengan pemisah desimal dan grup yang berbeda.

import Foundation
// The code below includes manual fix for whitespaces (for French case)
let strings = ["en_US": "My salary is $9,999.99",
               "fr_FR": "Mon salaire est 9 999,99€",
               "de_DE": "Mein Gehalt ist 9999,99€",
               "en_GB": "My salary is £9,999.99" ]
// Just for referce
let allPossibleDecimalSeparators = Set(Locale.availableIdentifiers.compactMap({ Locale(identifier: $0).decimalSeparator}))
print(allPossibleDecimalSeparators)
for str in strings {
    let locale = Locale(identifier: str.key)
    let valStr = str.value.filter{!($0.isWhitespace || $0 == Character(locale.groupingSeparator ?? ""))}
    print("Value String", valStr)

    let sc = Scanner(string: valStr)
    // we could do this more reliably with `filter` as well
    sc.charactersToBeSkipped = CharacterSet.decimalDigits.inverted
    sc.locale = locale

    print("Locale \(locale.identifier) grouping separator: |\(locale.groupingSeparator ?? "")| . Decimal separator: \(locale.decimalSeparator ?? "")")
    while !(sc.isAtEnd) {
        if let val = sc.scanDouble() {
            print(val)
        }

    }
}

Namun, ada masalah dengan pemisah yang bisa dipahami sebagai pembatas kata.

// This doesn't work. `Scanner` just ignores grouping separators because scanner tends to seek for multiple values
// It just refuses to ignore spaces or commas for example.
let strings = ["en_US": "$9,999.99", "fr_FR": "9999,99€", "de_DE": "9999,99€", "en_GB": "£9,999.99" ]
for str in strings {
    let locale = Locale(identifier: str.key)
    let sc = Scanner(string: str.value)
    sc.charactersToBeSkipped = CharacterSet.decimalDigits.inverted.union(CharacterSet(charactersIn: locale.groupingSeparator ?? ""))
    sc.locale = locale
    print("Locale \(locale.identifier) grouping separator: \(locale.groupingSeparator ?? "") . Decimal separator: \(locale.decimalSeparator ?? "")")
    while !(sc.isAtEnd) {
        if let val = sc.scanDouble() {
            print(val)
        }

    }
}
//     sc.scanDouble(representation: Scanner.NumberRepresentation) could help if there were .currency case

Tidak ada masalah untuk mendeteksi lokal secara otomatis. Perhatikan bahwa pengelompokanSeparator dalam bahasa Prancis dalam string "Mon salaire est 9 999,99 €" bukan spasi, meskipun itu dapat membuat persis seperti ruang (di sini tidak). Itulah mengapa kode di bawah ini berfungsi dengan baik tanpa !$0.isWhitespacekarakter yang difilter.

let stringsArr = ["My salary is $9,999.99",
                  "Mon salaire est 9 999,99€",
                  "Mein Gehalt ist 9.999,99€",
                  "My salary is £9,999.99" ]

let tagger = NSLinguisticTagger(tagSchemes: [.language], options: Int(NSLinguisticTagger.Options.init().rawValue))
for str in stringsArr {
    tagger.string = str
    let locale = Locale(identifier: tagger.dominantLanguage ?? "en")
    let valStr = str.filter{!($0 == Character(locale.groupingSeparator ?? ""))}
    print("Value String", valStr)

    let sc = Scanner(string: valStr)
    // we could do this more reliably with `filter` as well
    sc.charactersToBeSkipped = CharacterSet.decimalDigits.inverted
    sc.locale = locale

    print("Locale \(locale.identifier) grouping separator: |\(locale.groupingSeparator ?? "")| . Decimal separator: \(locale.decimalSeparator ?? "")")
    while !(sc.isAtEnd) {
        if let val = sc.scanDouble() {
            print(val)
        }

    }
}
// Also will fail if groupingSeparator == decimalSeparator (but don't think it's possible)
Paul B
sumber
-1

Saya menemukan lebih mudah dibaca untuk menambahkan ekstensi ke String sebagai berikut:

extension String {
    var doubleValue: Double {
        return (self as NSString).doubleValue
    }
}

dan kemudian Anda bisa menulis kode Anda:

myDouble = myString.doubleValue
Gutty1
sumber
-1

masalah saya adalah koma jadi saya menyelesaikannya dengan cara ini:

extension String {
    var doubleValue: Double {
        return Double((self.replacingOccurrences(of: ",", with: ".") as NSString).doubleValue)
    }
}
Murat Akdeniz
sumber
-3
var stringValue = "55"

var convertToDouble = Double((stringValue as NSString).doubleValue)
Mo Abdulmalik
sumber
-6

kita bisa menggunakan nilai CDouble yang akan diperoleh oleh myString.doubleValue

ANIL.MUNDURU
sumber
Kesalahan: 'String' tidak memiliki anggota bernama 'doubleValue'
Matthew Knippen
@ Matthew Ya tidak ada anggota yang disebut "nilai ganda", jadi kami dapat menggunakan Nilai
CDouble
1
en.wikipedia.org/wiki/... Lihat bilangan kompleks di sana dan baca dokumentasi referensi Swift .. Tidak ada CD ganda ... Apakah Anda berbicara tentang Swift atau bahasa lain? Dan maksud saya cepat tanpa ekstensi?
Adrian Sluyters