Swift - jak przekonwertować ciąg znaków na podwójny


242

Próbuję napisać program BMI w szybkim języku. Mam problem: jak przekonwertować ciąg znaków na podwójne?

W Objective-C mogę zrobić tak:

double myDouble = [myString doubleValue];

Ale jak mogę to osiągnąć w języku Swift?


1
Zmieniło się to w Swift 2, zobacz nową odpowiedź przy użyciu nowego inicjalizatora awaryjnego Double (): stackoverflow.com/a/32850058/276626
Paul Solt

Odpowiedzi:


205

Swift 4.2+ String to Double

Powinieneś użyć inicjatorów nowego typu do konwersji między typami String i numerycznymi (Double, Float, Int). Zwróci typ opcjonalny (Double?), Który będzie miał poprawną wartość lub zero, jeśli ciąg nie był liczbą.

Uwaga: Właściwość NSString doubleValue nie jest zalecana, ponieważ zwraca 0, jeśli wartość nie może zostać przekonwertowana (tj. Złe dane wprowadzone przez użytkownika).

let lessPrecisePI = Float("3.14")

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

Rozpakuj wartości, aby użyć ich za pomocą 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!)")
}

Możesz konwertować sformatowane liczby i walutę za pomocą NumberFormatterklasy.

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

Formaty walutowe

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

Przeczytaj więcej na moim blogu o konwertowaniu ciągów znaków na podwójne (i walutę) .


2
Innym problemem jest to, że nie obsługuje liczb w różnych ustawieniach narodowych innych niż 1 000,00, jeśli użyjesz innych formatów, takich jak 1 000,00, odetnie 2 cyfry po przecinku na końcu. Przynajmniej tak dzieje się w przypadku Celu C. - Zgodnie z dokumentacją Apple: (Nie są one zgodne z ustawieniami regionalnymi) Poniższe metody wygody pomijają początkowe znaki spacji (whitespaceSet) i ignorują końcowe znaki. Nie są świadomi ustawień regionalnych. NSScanner lub NSNumberFormatter może być wykorzystywany do bardziej wydajnego i opartego na ustawieniach regionalnych analizowania liczb.
mskw

@mskw Dodałem dodatkowe szczegóły dotyczące korzystania z NumberFormatter do analizowania waluty. W moim kodzie połączę ze sobą wiele prób formatowania przy użyciu składni if ​​/ let, aby móc analizować zarówno liczby sformatowane w walucie (1 000,00 USD), jak i liczby sformatowane (1000). Nie zawsze wiesz, jak użytkownik wprowadzi liczby, więc możliwość obsługi obu jest idealna z grupą instrukcji if / let.
Paul Solt

276

Swift 2 Update Są nowe inicjalizatory failable które pozwalają to zrobić w bardziej idiomatyczne i bezpieczny sposób (jak wiele odpowiedzi zauważyli, podwójna wartość NSString nie jest bardzo bezpieczne, ponieważ zwraca 0 dla wartości spoza numerycznych. Oznacza to, że doubleValueod "foo"i "0"są to samo.)

let myDouble = Double(myString)

Zwraca to wartość opcjonalną, więc w przypadkach takich jak przekazywanie w "foo"miejsce, w którym doubleValuezwróciłoby 0, zwracany jest niezawodny intializer nil. Można użyć guard, if-letlub mapdo obsługiOptional<Double>

Oryginalny post: Nie musisz używać konstruktora NSString, jak proponuje zaakceptowana odpowiedź. Możesz po prostu to przełączyć w następujący sposób:

(swiftString as NSString).doubleValue

5
ohai, Jarsen. Wadą tego podejścia jest to, że nie zawiedzie, jeśli łańcuch nie będzie poprawnym podwójnym. Zamiast tego dostaniesz 0,0. Oznacza to, że wynik - [NSString doubleValue]jest Doubleszybki w zastosowaniu do Double?( Optional<Double>). Różni się to od funkcji Swift String, toInt()która zwraca Int?i stwierdza w dokumentach, że „... akceptuje ciągi pasujące do wyrażenia regularnego„ [- +]? [0-9] + ”tylko.”
Derrick Hathaway,

Tak, używanie .toInt()byłoby lepsze. Była to jednak raczej odpowiedź na to, jak zrobić dokładnie to samo, ale w Swift.
Jarsen

Takie podejście ściśle łączy Cię z Foundation i prawdopodobnie nie będzie działać na żadnych implementacjach Swift innych niż Apple.
Erik Kerber,

5
W Swift 2.0 dostępny jest Double.init?(_ text: String)teraz awaryjny inicjator.
mixel

3
To nie jest najlepsze podejście. Nie powiedzie się w zależności od separatora dziesiętnego. Będzie dobrze z „.” ale nie z „,”. NSNumberFormatter będzie obsługiwał separator dziesiętny używany w bieżącej lokalizacji.
Julian Król

75

Aby uzyskać nieco bardziej szybkie uczucie, użycie NSFormatter()unika rzutowania na NSStringi zwraca, nilgdy ciąg nie zawiera Doublewartości (np. „Test” nie zwróci 0.0).

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

Alternatywnie, rozszerzając Stringtyp Swift :

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

i używaj go w następujący sposób toInt():

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

Zwraca to opcję opcjonalną, Double?którą należy rozpakować.

Albo z wymuszonym rozpakowaniem:

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

lub z instrukcją if let:

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

Aktualizacja: W celu lokalizacji bardzo łatwo jest zastosować ustawienia narodowe do NSFormatter w następujący sposób:

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

Na koniec możesz użyć NSNumberFormatterCurrencyStyleformatyzatora, jeśli pracujesz z walutami, w których łańcuch zawiera symbol waluty.


Podoba mi się pomysł rozszerzenia klasy String dla aplikacji, które będą korzystać z konwersji w wielu miejscach. Ale nie widzę korzyści ze złożoności wywoływania NSNumberFormatter, ponieważ rzutowanie na NSString i używanie .doubleValue wydaje się co najmniej tak bezpośrednie, łatwiejsze do odczytania i zapamiętania.
wyczyść

12
W rzeczywistości zaletą użycia NSNumberFormatter () jest to, że metoda numberFromString: zwróci zero, jeśli ciąg znaków zawiera znaki, które nie tworzą podwójnej liczby. Problem z doubleValue na NSString polega na tym, że zawsze zwróci double (na przykład 0.0 dla „testu”) niezależnie od tego. Więc jeśli masz do czynienia z wszelkiego rodzaju ciągami znaków i chcesz sprawdzić, czy ciąg znaków jest podwójny, żadnych dodatkowych znaków, skorzystaj z NSNumberFormatter.
dirkgroten

4
Nie udaje się to po francusku.
Peter K.,

1
To świetne rozwiązanie, ale użycie tylko tego kodu nie będzie działać w krajach, w których przecinki są używane jako separatory (w tym Francja jako @PeterK. Wspomniane). Próbowałem napisać komentarz z rozwiązaniem, ale było to zbyt długo, więc zamiast tego musiałem udzielić odpowiedzi. Proszę bardzo: zmodyfikowane rozwiązanie
Jacob R

53

Inną opcją jest przekonwertowanie tego na NSStringi użycie tego:

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

13
Chciałbym, żeby był to lepszy sposób. Skąd mam wiedzieć, na przykład, czy parsowanie się nie powiodło?
Ryan Hoffman

2
@RyanHoffman Niestety, umowa o podwójnej wartości NSString nigdy tego nie zapewniła. Otrzymasz tylko 0,0, jeśli ciąg nie rozpocznie się od prawidłowej reprezentacji liczby, OGROMNEJ_WARUNKU i -WIELKIEJ_WALNOŚCI w przypadku przepełnienia / niedopełnienia. Jeśli chcesz wiedzieć, dlaczego parsowanie nie powiodło się, uważam, że musisz przyjrzeć się NSNumberFormatter, który został zaprojektowany do obsługi konwersji liczb / ciągów w bardziej niezawodny sposób.
Jarsen

Ponieważ znalezienie tej odpowiedzi może być trudne, oto ona:(swiftString as NSString).doubleValue
LearnCocos2D,

24

Oto metoda rozszerzenia, która pozwala po prostu wywołać doubleValue () na łańcuchu Swift i uzyskać podwójne odwrócenie (przykładowe wyjście jest pierwsze)

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

Oto metoda rozszerzenia:

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

Brak sprawdzania błędów, ale możesz go dodać, jeśli potrzebujesz.


20

Począwszy od wersji Swift 1.1, można bezpośrednio przejść Stringdo const char *parametru.

import Foundation

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

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

Jeśli nie lubisz przestarzałych atof:

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

Jedno zastrzeżenie: zachowanie konwersji jest inne niż NSString.doubleValue.

atofi strtodzaakceptuj 0xpoprzedzony ciąg szesnastkowy:

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

Jeśli wolisz .doubleValuezachowanie, nadal możemy korzystać z CFStringmostkowania:

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

Jestem fanem tego podejścia zamiast castingu do NSString.
Sam Soffes

10

W Swift 2.0 najlepszym sposobem jest unikanie myślenia jak programista Objective-C. Dlatego nie powinieneś „konwertować ciągu na podwójny”, ale „inicjować podwójny z ciągu”. Dokument Apple tutaj: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_

Jest to opcjonalny init, więc możesz użyć zerowego operatora koalescencyjnego (??), aby ustawić wartość domyślną. Przykład:

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

Double.init?(_ text: String)stają się dostępne w Swift 2.0. Powinieneś o tym wspomnieć. Inne odpowiedzi tutaj nie są dlatego, że ludzie myślą jak programiści Objective-C, ale dlatego, że ten inicjator nie był wcześniej dostępny.
mixel

Rzeczywiście masz rację. Jest to dostępne tylko w Swift 2.0, wspomnę o tym :) Ale podobnie jak w innych językach inicjujesz typ z innym i nie powinieneś oczekiwać, że typ będzie w stanie przekonwertować na inny. Długa debata, ale jako programista Obj-C mam wiele złych praktyk podczas kodowania za pomocą Swift i to jest jedna z nich :)
Toom

10

W SWIFT 3 możesz użyć:

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

Uwaga: - Jeśli ciąg znaków zawiera znaki inne niż cyfry lub separatory grupy lub liczby dziesiętne odpowiednie dla danego regionu, analiza nie powiedzie się. - Wszelkie początkowe lub końcowe znaki separatora spacji w ciągu są ignorowane. Na przykład ciągi „5”, „5” i „5” dają liczbę 5.

Zaczerpnięte z dokumentacji: https://developer.apple.com/reference/foundation/numberformatter/1408845-number


10

Nie widziałem odpowiedzi, której szukałem. Po prostu zamieszczam tutaj moje, na wypadek, gdyby to mogło pomóc każdemu. Ta odpowiedź jest ważna tylko wtedy, gdy nie potrzebujesz określonego formatu .

Szybki 3

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

9

Spróbuj tego:

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

UWAGA

Usunięto w wersji Beta 5. To już nie działa?


1
bridgeToObjectiveC () został usunięty w Xcode 6 Beta 5. Metoda pana Smileya jest najszybsza, jaką w tej chwili
znalazłem

7

Opiera się to na odpowiedzi @Ryu

Jego rozwiązanie jest świetne, dopóki jesteś w kraju, w którym kropki są używane jako separatory. Domyślnie NSNumberFormatterużywa ustawień regionalnych urządzeń. Dlatego nie powiedzie się to we wszystkich krajach, w których przecinek jest używany jako domyślny separator (w tym Francja, jak wspomniano @PeterK.), Jeśli liczba używa kropek jako separatorów (co zwykle ma miejsce). Aby ustawić ustawienia regionalne tego NSNumberFormatter na US, a zatem użyj kropek, ponieważ separatory zastępują linię

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

z

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

Dlatego pełny kod staje się

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

Aby z tego skorzystać, wystarczy zadzwonić "Your text goes here".toDouble()

Zwróci to opcjonalne Double?

Jak wspomniano w @Ryu, możesz albo wymusić rozpakowanie:

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

lub użyj if letoświadczenia:

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

1
To jest właściwa odpowiedź. Wersja Swift 3 będzie 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
    }
}

6

Swift 4.0

Spróbuj tego

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

6

Szybki: 4 i 5

Można to zrobić na dwa sposoby:

  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)

Używaj go w dowolny sposób, zgodnie z potrzebą kodu.


Pierwsza metoda nie działa dla mnie, jednak druga działa całkiem dobrze.
Saurabh

@Saurabh, Czy możesz rozwinąć więcej informacji na temat tego, jaki był twój ciąg znaków?
Abhirajsinh Thakore

5

Sprawdź to na placu zabaw!

let sString = "236.86"

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

Przy okazji w moim Xcode

.toDouble () - nie istnieje

.doubleValue tworzy wartość 0.0 z ciągów nienumerycznych ...


4

1.

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

2)

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

Może ci to pomóc.


4

Jak już wspomniano, najlepszym sposobem na osiągnięcie tego jest rzutowanie bezpośrednie:

(myString as NSString).doubleValue

Opierając się na tym, możesz stworzyć eleganckie natywne rozszerzenie Swift String:

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

Pozwala to na bezpośrednie użycie:

myString.doubleValue

Który wykona dla ciebie casting. Jeśli Apple doda doubleValuenatywny ciąg, wystarczy usunąć rozszerzenie, a reszta kodu automatycznie się skompiluje!


Metoda Apple'a zostanie nazwana .toDouble ... tak samo jak toInt. To dziwne pominięcie. Prawdopodobnie zostanie naprawiony w przyszłej wersji Swift. Najbardziej podoba mi się metoda rozszerzenia, utrzymanie kodu w czystości.
n13


4

SWIFT 3

Aby wyczyścić, obecnie istnieje domyślna metoda:

public init?(_ text: String)z Doubleklasą.

Może być stosowany do wszystkich klas.

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


2

Rozszerzenie z opcjonalnymi ustawieniami narodowymi

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

Swift 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
Dodałem przykład Swift 3.1. Co rozumiesz przez „... i dodaj przykład dla ustawień regionalnych”? 🙂
imike

1

Lub możesz zrobić:

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

1

Możesz użyć StringEx . Rozciąga Stringsię na konwersje ciągów na liczby, w tym toDouble().

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

Sprawdza ciąg i kończy się niepowodzeniem, jeśli nie można go przekonwertować na podwójny.

Przykład:

import StringEx

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

1

Szybki 4

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

0

Co również działa:

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

UWAGA: „scanDouble” jest przestarzałe w iOS 13.0
uplearnedu.com


0

Używanie Scannerw niektórych przypadkach jest bardzo wygodnym sposobem wydobywania liczb z łańcucha. I jest prawie tak potężny, jak w NumberFormatterprzypadku dekodowania i radzenia sobie z różnymi formatami liczb i lokalizacjami. Może wyodrębniać liczby i waluty z różnymi separatorami dziesiętnymi i grupowymi.

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

    }
}

Istnieją jednak problemy z separatorami, które można by traktować jako ograniczniki słów.

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

Nie ma problemu z automatycznym wykryciem ustawień regionalnych. Zauważ, że groupingSeparator w języku francuskim w łańcuchu „Mon salaire est 9 999,99 €” nie jest spacją, chociaż może renderować się dokładnie jako spacja (tutaj nie ma). Właśnie dlatego poniższy kod działa dobrze bez !$0.isWhitespaceodfiltrowywania znaków.

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

Bardziej czytelne wydaje się dodanie rozszerzenia do ciągu w następujący sposób:

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

i wtedy możesz po prostu napisać kod:

myDouble = myString.doubleValue

-1

moim problemem był przecinek, więc rozwiązałem go w ten sposób:

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

-3
var stringValue = "55"

var convertToDouble = Double((stringValue as NSString).doubleValue)

-6

możemy użyć wartości CDouble, która zostanie uzyskana przez myString.doubleValue


Błąd: ciąg „String” nie ma elementu o nazwie „doubleValue”
Matthew Knippen,

@Matthew Tak, nie ma członka o nazwie „podwójna wartość”, więc możemy użyć CDouble Value
ANIL.MUNDURU

1
en.wikipedia.org/wiki/... Odwołaj się do liczb zespolonych i przeczytaj dokumentację referencyjną Swift. Nie ma CDp2 ... Czy mówisz o Swift lub innym języku? Mam na myśli szybkie bez rozszerzeń?
Adrian Sluyters,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.