स्विफ्ट - स्ट्रिंग को डबल में कैसे बदलें


242

मैं तेज भाषा में बीएमआई कार्यक्रम लिखने की कोशिश कर रहा हूं। और मुझे यह समस्या मिली: स्ट्रिंग को डबल में कैसे बदलें?

ऑब्जेक्टिव-सी में, मैं इस तरह कर सकता हूं:

double myDouble = [myString doubleValue];

लेकिन मैं इसे स्विफ्ट भाषा में कैसे हासिल कर सकता हूं?


1
: यह स्विफ्ट 2 में बदल गया है, नई डबल () failable प्रारंभकर्ता का उपयोग कर नए जवाब देखने stackoverflow.com/a/32850058/276626
पॉल सोल्ट

जवाबों:


205

स्विफ्ट 4.2+ स्ट्रिंग टू डबल

आपको स्ट्रिंग और संख्यात्मक प्रकारों (डबल, फ्लोट, इंट) के बीच कनवर्ट करने के लिए नए प्रकार के इनिशियलाइज़र का उपयोग करना चाहिए। यह एक वैकल्पिक प्रकार (डबल?) लौटाएगा जिसका सही मूल्य या शून्य होगा यदि स्ट्रिंग एक संख्या नहीं थी।

नोट: NSString doubleValue प्रॉपर्टी की सिफारिश नहीं की गई है क्योंकि यह 0 लौटाता है यदि मान परिवर्तित नहीं किया जा सकता है (यानी: खराब उपयोगकर्ता इनपुट)।

let lessPrecisePI = Float("3.14")

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

मानों को अनप्रेप करें यदि वे / लेट का उपयोग करके उपयोग करते हैं

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

आप NumberFormatterवर्ग का उपयोग करके स्वरूपित संख्याओं और मुद्रा को परिवर्तित कर सकते हैं ।

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

मुद्रा प्रारूप

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

स्ट्रिंग को डबल प्रकार (और मुद्रा) में परिवर्तित करने के बारे में मेरे ब्लॉग पोस्ट पर और पढ़ें ।


2
एक और मुद्दा यह है कि यह 1,000.00 के अलावा अन्य विभिन्न स्थानों में संख्याओं का समर्थन नहीं करता है, यदि आप 1 000,00 जैसे अन्य स्वरूपों का उपयोग करते हैं तो यह अंत में 2 दशमलव को काट देगा। कम-से-कम यही उद्देश्य-सी के लिए हो रहा है। - Apple दस्तावेज़ीकरण के अनुसार: (वे स्थानीय-जागरूक नहीं हैं) निम्नलिखित सुविधा विधियाँ प्रारंभिक स्थान वर्ण (व्हाट्सएपसेट) को छोड़ देती हैं और अनुगामी पात्रों को अनदेखा कर देती हैं। वे स्थानीय-जागरूक नहीं हैं। NSScanner या NSNumberFormatter का उपयोग संख्याओं के अधिक शक्तिशाली और स्थानीय-जागरूक पार्सिंग के लिए किया जा सकता है।
mskw

@mskw मैंने मुद्रा को पार्स करने के लिए NumberFormatter का उपयोग करने पर अतिरिक्त विवरण जोड़ा है। अपने कोड में मैं एक साथ कई फ़ॉर्मेटर को स्ट्रिंग / if सिंटैक्स का उपयोग करके बदलने का प्रयास करूँगा ताकि मैं दोनों मुद्रा स्वरूपित संख्याओं ($ 1,000.00) या स्वरूपित संख्याओं (1,000) को पार्स कर सकूँ। आपको हमेशा यह नहीं पता होता है कि उपयोगकर्ता संख्याओं को कैसे दर्ज करेगा, इसलिए दोनों का समर्थन करने में सक्षम होने के कारण अगर / चलो बयानों के एक समूह के साथ आदर्श है।
पॉल सोल्ट

276

स्विफ्ट 2 अपडेट नए फेलियर इनिशियलाइज़र हैं जो आपको इसे अधिक मुहावरेदार और सुरक्षित तरीके से करने की अनुमति देते हैं (जैसा कि कई जवाबों में उल्लेख किया गया है, एनएसएसट्रिंग का दोहरा मूल्य बहुत सुरक्षित नहीं है क्योंकि यह गैर-संख्या मानों के लिए 0 देता है। इसका मतलब है कि यह doubleValueहैं "foo"और "0"हैं वही।)

let myDouble = Double(myString)

यह एक वैकल्पिक रिटर्न देता है, इसलिए ऐसे मामलों में "foo"जहां उत्तीर्ण doubleValueहोने के बाद 0 वापस आ गया हो, फाल्ट इंटेलाइजर वापस आ जाएगा nil। आप एक का उपयोग कर सकते guard, if-letया mapसंभाल करनेOptional<Double>

मूल पोस्ट: आपको NSString कंस्ट्रक्टर का उपयोग करने की आवश्यकता नहीं है जैसे स्वीकृत उत्तर का प्रस्ताव है। आप बस इसे इस तरह से पा सकते हैं:

(swiftString as NSString).doubleValue

5
ओह, जार्सन। इस दृष्टिकोण के लिए एक नकारात्मक पक्ष यह है कि यह विफल नहीं होगा यदि स्ट्रिंग एक वैध डबल नहीं है। इसके बदले आपको सिर्फ 0.0 मिलेगी। है यही कारण है, का परिणाम - [NSString doubleValue]है Doubleके रूप में करने के लिए apposed तेजी में Double?( Optional<Double>)। यह स्विफ्ट स्ट्रिंग फ़ंक्शन से अलग है toInt()जो Int?डॉक्स में लौटता है और बताता है कि यह "... स्ट्रिंग्स को स्वीकार करता है जो नियमित अभिव्यक्ति से मेल खाता है" [- +]? [0-9] + "केवल।"
डेरिक हैथवे

हां, का उपयोग .toInt()करना बेहतर होगा। हालांकि, यह एक ही बात करने के लिए अधिक जवाब था, लेकिन स्विफ्ट में।
जर्सन

यह दृष्टिकोण आपको कसकर जोड़े में बांधता है, और संभवतः स्विफ्ट के किसी भी गैर-एप्पल कार्यान्वयन पर काम नहीं करेगा।
एरिक कर्बर

5
स्विफ्ट 2.0 में Double.init?(_ text: String)अब उपलब्ध उपलब्ध है।
मिश्रण

3
यह सबसे अच्छा तरीका नहीं है। यह दशमलव विभाजक के आधार पर विफल हो जाएगा। यह 'के साथ ठीक रहेगा।' लेकिन ',' के साथ नहीं। NSNumberFormatter वर्तमान स्थानीयकरण में उपयोग किए गए दशमलव विभाजक का समर्थन करेगा।
जूलियन क्राल

75

थोड़ी अधिक स्विफ्ट भावना के NSFormatter()लिए NSString, कास्टिंग का उपयोग करने से बचा जाता है , और nilजब स्ट्रिंग में कोई Doubleमान नहीं होता है (उदाहरण के लिए "परीक्षण" वापस नहीं आएगा 0.0)।

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

वैकल्पिक रूप से, स्विफ्ट के Stringप्रकार का विस्तार :

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

और इसका उपयोग करें toInt():

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

यह एक वैकल्पिक रिटर्न देता है Double?जिसे अलिखित करना होता है।

या तो जबरजस्ती के साथ:

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

या यदि कोई वक्तव्य देता है:

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

अद्यतन: स्थानीयकरण के लिए, NSFormatter पर निम्नानुसार स्थानों को लागू करना बहुत आसान है:

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

अंत में, आप NSNumberFormatterCurrencyStyleफॉर्मेटर पर उपयोग कर सकते हैं यदि आप उन मुद्राओं के साथ काम कर रहे हैं जहां स्ट्रिंग में मुद्रा प्रतीक होता है।


मुझे उन ऐप्स के लिए स्ट्रिंग क्लास का विस्तार करने का विचार पसंद है जो रूपांतरण कई स्थानों का उपयोग करेंगे। लेकिन मुझे NSNumberFormatter को लागू करने की जटिलता का लाभ नहीं दिखता है, क्योंकि कलाकारों को NSString और उपयोग करने के लिए। DoubleValue कम से कम प्रत्यक्ष रूप से लगता है, और पढ़ने और याद रखने में आसान है।
साफ़ करें

12
वास्तव में NSNumberFormatter () का उपयोग करने का लाभ यह है कि नंबरग्रोमस्ट्रिंग: विधि में एनआईएल वापस आ जाएगा यदि स्ट्रिंग में ऐसे अक्षर हैं जो एक डबल नहीं बनाते हैं। NSString पर DoubleValue के साथ समस्या यह है कि यह हमेशा परवाह किए बिना एक डबल (0.0 "परीक्षण" उदाहरण के लिए) लौटाएगा। इसलिए यदि आप सभी प्रकार के तार के साथ काम कर रहे हैं और आप परीक्षण करना चाहते हैं कि क्या स्ट्रिंग सिर्फ एक डबल है, कोई अतिरिक्त वर्ण नहीं है, तो NSNumberFormatter का उपयोग करने का तरीका है।
dirkgroten

4
यह फ्रेंच पर विफल है।
पीटर के।

1
यह एक महान समाधान है, लेकिन केवल इस कोड का उपयोग करने से यह उन देशों में काम नहीं करेगा जहां अल्पविराम का उपयोग विभाजक के रूप में किया जाता है (फ्रांस के रूप में PPeterK उल्लेखित है)। मैंने समाधान के साथ एक टिप्पणी लिखने की कोशिश की, लेकिन यह बहुत लंबा था इसलिए मुझे इसके बजाय इसका जवाब देना पड़ा। यहाँ आप जाते हैं: संशोधित समाधान
याकूब आर

53

यहाँ एक और विकल्प इसे परिवर्तित NSStringकर रहा है और इसका उपयोग कर रहा है:

let string = NSString(string: mySwiftString)
string.doubleValue

13
काश ऐसा करने का एक अच्छा तरीका होता। उदाहरण के लिए, यदि पार्सिंग विफल हुआ, तो मुझे कैसे पता चलेगा।
रयान हॉफमैन

2
@RyanHoffman दुर्भाग्य से NSString doubleValue अनुबंध ने कभी भी ऐसा नहीं किया है। यदि आप स्ट्रिंग संख्या के वैध प्रतिनिधित्व के साथ शुरू नहीं करते हैं, तो आपको केवल 0.0 ही मिलता है। यदि आप यह जानना चाहते हैं कि पार्सिंग विफल क्यों हुआ, तो मेरा मानना ​​है कि आपको NSNumberFormatter पर ध्यान देने की आवश्यकता है, जिसे अधिक मजबूत तरीके से संख्या / स्ट्रिंग रूपांतरण को संभालने के लिए डिज़ाइन किया गया था।
जर्सन

चूँकि उस उत्तर को खोजना मुश्किल हो सकता है, यहाँ यह है:(swiftString as NSString).doubleValue
LearnCocos2D

24

यहाँ एक विस्तार विधि है जो आपको स्विफ्ट स्ट्रिंग पर केवल डबलवैल्यू () कॉल करने की अनुमति देती है और एक डबल बैक मिलता है (उदाहरण आउटपुट पहले आता है)

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

यहाँ विस्तार विधि है:

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

कोई त्रुटि जाँच नहीं है, लेकिन आप इसे जोड़ सकते हैं यदि आपको इसकी आवश्यकता है।


20

स्विफ्ट 1.1 के रूप में, आप सीधे पैरामीटर Stringको पास कर सकते हैं const char *

import Foundation

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

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

अगर आपको पदावनति पसंद नहीं है atof:

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

एक चेतावनी: रूपांतरण का व्यवहार इससे अलग है NSString.doubleValue

atofऔर उपसर्ग हेक्स स्ट्रिंग को strtodस्वीकार करें 0x:

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

यदि आप .doubleValueव्यवहार पसंद करते हैं, तो हम अभी भी CFStringब्रिजिंग का उपयोग कर सकते हैं :

let str = "0xff"
atof(str)                      // -> 255.0
strtod(str, nil)               // -> 255.0
CFStringGetDoubleValue(str)    // -> 0.0
(str as NSString).doubleValue  // -> 0.0

मैं कास्टिंग के बजाय इस दृष्टिकोण का प्रशंसक हूं NSString
सैम सोफेस 13

10

स्विफ्ट 2.0 में उद्देश्यपूर्ण सी डेवलपर की तरह सोचने से बचने का सबसे अच्छा तरीका है। इसलिए आपको "स्ट्रिंग को डबल में कनवर्ट नहीं करना चाहिए" लेकिन आपको "स्ट्रिंग से डबल इनिशियलाइज़ करना चाहिए"। Apple डॉक यहां पर: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structure/Double/s:FSdcFMSdFSSGSqSd_

यह एक वैकल्पिक init है ताकि आप डिफ़ॉल्ट मान सेट करने के लिए nil coalescing ऑपरेटर (??) का उपयोग कर सकें। उदाहरण:

let myDouble = Double("1.1") ?? 0.0

Double.init?(_ text: String)स्विफ्ट 2.0 में उपलब्ध हो जाते हैं। आपको इसका उल्लेख करना चाहिए। अन्य उत्तर यहां इसलिए नहीं हैं क्योंकि लोग ऑब्जेक्टिव-सी डेवलपर्स की तरह सोचते हैं बल्कि इसलिए कि यह इनिशलाइज़र पहले उपलब्ध नहीं था।
मिश्रण

वास्तव में आप सही हैं। यह केवल स्विफ्ट 2.0 में उपलब्ध है, मैं इसका उल्लेख करूंगा :) लेकिन अन्य भाषाओं की तरह आप एक प्रकार को दूसरे के साथ आरंभ करते हैं और एक प्रकार को दूसरे में बदलने में सक्षम होने की उम्मीद नहीं करनी चाहिए। लंबी बहस लेकिन एक ओबज-सी डेवलपर के रूप में मैं स्विफ्ट के साथ कोडिंग करते समय कई बुरे व्यवहार करता हूं और यह उनमें से एक है :)
Toom

10

पर स्विफ्ट 3 , आप का उपयोग कर सकते हैं:

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

नोट: - यदि एक स्ट्रिंग में संख्यात्मक अंक या स्थानीय-उपयुक्त समूह या दशमलव विभाजकों के अलावा कोई भी वर्ण है, तो पार्सिंग विफल हो जाएगी। - एक स्ट्रिंग में किसी भी अग्रणी या अनुगामी अंतरिक्ष विभाजक पात्रों को अनदेखा किया जाता है। उदाहरण के लिए, स्ट्रिंग्स "5", "5", और "5" सभी संख्या 5 का उत्पादन करते हैं।

दस्तावेज़ीकरण से लिया गया: https://developer.apple.com/reference/foundation/numberformatter/140888-number


10

मैंने वह उत्तर नहीं देखा है जिसकी मुझे तलाश थी। मैं यहाँ सिर्फ मेरा पोस्ट करता हूँ अगर यह किसी की मदद कर सकता है। यह उत्तर केवल तभी मान्य होता है जब आपको किसी विशिष्ट प्रारूप की आवश्यकता नहीं होती है

स्विफ्ट 3

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

9

इसे इस्तेमाल करे:

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

ध्यान दें

बीटा 5 में निकाला गया। यह अब काम नहीं करता है?


1
BridgeToObjectiveC () को Xcode 6 Beta 5 में हटा दिया गया है। श्री स्माइली का तरीका इस समय सबसे तेज है
faraquet99

7

यह @Ryu के उत्तर पर बन रहा है

उसका समाधान तब तक बहुत अच्छा है जब तक आप उस देश में हैं जहाँ डॉट्स को विभाजक के रूप में उपयोग किया जाता है। डिफ़ॉल्ट रूप NSNumberFormatterसे डिवाइस लोकेल का उपयोग करता है। इसलिए यह उन सभी देशों में विफल हो जाएगा जहां अल्पविराम का उपयोग डिफ़ॉल्ट विभाजक के रूप में किया जाता है (फ्रांस के रूप में @PeterK उल्लेख किया गया है) यदि संख्या विभाजक के रूप में डॉट्स का उपयोग करती है (जो कि सामान्य रूप से मामला है)। इस NSNumberFormatter के स्थान को अमेरिका के रूप में सेट करने के लिए और इस प्रकार डॉट्स का उपयोग करें क्योंकि विभाजक लाइन को प्रतिस्थापित करते हैं

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

साथ में

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

इसलिए पूरा कोड बन जाता है

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

इसका उपयोग करने के लिए, बस कॉल करें "Your text goes here".toDouble()

यह एक वैकल्पिक लौटाएगा Double?

जैसा कि @Ryu ने उल्लेख किया है कि आप या तो मजबूर कर सकते हैं:

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

या एक if letबयान का उपयोग करें :

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

1
यह सही जवाब है। स्विफ्ट 3 संस्करण होगा NumberFormatter().number(from: myString)?.doubleValue
निकोलस लीओ

7

स्विफ्ट 4

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


6

स्विफ्ट: 4 और 5

ऐसा करने के लिए संभवतः दो तरीके हैं:

  1. स्ट्रिंग -> इंट -> डबल:

    let strNumber = "314"
    if let intFromString = Int(strNumber){
        let dobleFromInt = Double(intFromString)
        print(dobleFromInt)
    }
  2. स्ट्रिंग -> एनएसएसट्रिंग -> डबल

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

आप इसे वैसे भी उपयोग करें जैसे आपको कोड की आवश्यकता हो।


पहला तरीका मेरे लिए काम नहीं करता है, हालांकि दूसरा बहुत अच्छा काम करता है।
सौरभ

@ सौरभ, क्या आप और अधिक विस्तार से बता सकते हैं कि आपका तार क्या था?
अभिराजसिंह ठाकोर

5

कृपया इसे खेल के मैदान पर जांचें!

let sString = "236.86"

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

वैसे मेरे Xcode में

.toDouble () - मौजूद नहीं है

.doubleValue संख्यात्मक मान नहीं से 0.0 मान बनाएँ ...


4

1।

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

2।

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

आपके लिए यह मदद हो सकती है।


4

जैसा कि पहले ही बताया गया है, इसे प्राप्त करने का सबसे अच्छा तरीका प्रत्यक्ष कास्टिंग है:

(myString as NSString).doubleValue

उस से बिल्डिंग, आप एक चालाक देशी स्विफ्ट स्ट्रिंग एक्सटेंशन बना सकते हैं:

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

यह आपको सीधे उपयोग करने की अनुमति देता है:

myString.doubleValue

जो आपके लिए कास्टिंग करेगा। यदि Apple doubleValueदेशी स्ट्रिंग में जोड़ता है तो आपको केवल एक्सटेंशन निकालने की आवश्यकता होती है और आपके बाकी कोड स्वचालित रूप से ठीक संकलन करेंगे!


Apple की विधि को .toDouble कहा जाएगा। यह एक अजीब चूक है। भविष्य के स्विफ्ट संस्करण में सुधार किए जाने की संभावना है। मुझे एक्सटेंशन विधि सबसे अच्छी लगती है, कोड को साफ रखता है।
n13

वापसी मूल्य एक डबल फ्लोट नहीं होना चाहिए
लियो डबस

4

स्विफ्ट 3

स्पष्ट करने के लिए, आजकल एक डिफ़ॉल्ट विधि है:

public init?(_ text: String)के Doubleवर्ग।

इसका उपयोग सभी वर्गों के लिए किया जा सकता है।

let c = Double("-1.0") let f = Double("0x1c.6") let i = Double("inf") , आदि।


2

वैकल्पिक स्थान के साथ विस्तार

स्विफ्ट 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
    }
}

स्विफ्ट 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
        }
    }
}

1
मैंने स्विफ्ट 3.1 का उदाहरण जोड़ा है। "... और लोकेल के लिए एक उदाहरण जोड़ें" से आपका क्या मतलब है? 🙂
imike

1

या आप कर सकते हैं:

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

1

आप StringEx का उपयोग कर सकते हैं । यह Stringसहित स्ट्रिंग से संख्या रूपांतरणों तक फैली हुई है toDouble()

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

यह स्ट्रिंग को सत्यापित करता है और विफल रहता है अगर इसे डबल में परिवर्तित नहीं किया जा सकता है।

उदाहरण:

import StringEx

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


0

क्या काम करता है:

// 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.

नोट: 'ScanDouble' को iOS 13.0
uplearnedu.com


0

Scannerकुछ मामलों में उपयोग करना एक स्ट्रिंग से संख्या निकालने का एक बहुत ही सुविधाजनक तरीका है। और यह लगभग उतना ही शक्तिशाली है NumberFormatterजब यह अलग-अलग संख्या प्रारूपों और स्थानों के साथ डिकोडिंग और निपटने के लिए आता है। यह विभिन्न दशमलव और समूह विभाजकों के साथ संख्या और मुद्राएं निकाल सकता है।

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

    }
}

हालांकि, ऐसे विभाजकों के साथ समस्याएँ हैं जिन्हें शब्द सीमांकक के रूप में माना जा सकता है।

// 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

ऑटो का पता लगाने के लिए कोई समस्या नहीं है। ध्यान दें कि स्ट्रिंग में सोम स्थान पर फ्रेंच लोकेल में ग्रुपिंगसेपरेटर "मोन सैलेर एस्ट 9 999,99 €" एक स्थान नहीं है, हालांकि यह बिल्कुल अंतरिक्ष के रूप में प्रस्तुत कर सकता है (यहां यह नहीं है)। इसीलिए नीचे दिया गया कोड बिना !$0.isWhitespaceवर्णों के ठीक काम करता है ।

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)

-1

मैं स्ट्रिंग के लिए एक एक्सटेंशन जोड़ने के लिए और अधिक पठनीय लगता है:

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

और फिर आप बस अपना कोड लिख सकते हैं:

myDouble = myString.doubleValue

-1

मेरी समस्या अल्पविराम थी इसलिए मैंने इसे इस तरह हल किया:

extension String {
    var doubleValue: Double {
        return Double((self.replacingOccurrences(of: ",", with: ".") as NSString).doubleValue)
    }
}


-6

हम CDSt Value का उपयोग कर सकते हैं जो myString.doubleValue द्वारा प्राप्त किया जाएगा


त्रुटि: 'स्ट्रिंग' में 'डबलवैल्यू' नाम का कोई सदस्य नहीं है
मैथ्यू निप्पन

@ मैथ्यू हाँ "डबल वैल्यू" नामक कोई सदस्य नहीं है, इसलिए हम सीडी डबल वैल्यू
ANIL.MUNDURU

1
en.wikipedia.org/wiki/… वहां के जटिल नंबरों का संदर्भ लें और स्विफ्ट संदर्भ दस्तावेज पढ़ें .. कोई सीडी डबल नहीं है ... क्या आप स्विफ्ट या किसी अन्य भाषा के बारे में बात कर रहे हैं? और मेरा मतलब है कि बिना एक्सटेंशन के स्विफ्ट?
एड्रियन स्लुइटर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.