programing

Swift - 문자열을 이중으로 변환하는 방법

linuxpc 2023. 4. 11. 21:45
반응형

Swift - 문자열을 이중으로 변환하는 방법

BMI 프로그램을 빠른 언어로 작성하려고 합니다.그런데 문제가 생겼어요. 어떻게 스트링을 더블로 바꿀 수 있죠?

Objective-C에서는 다음과 같이 할 수 있습니다.

double myDouble = [myString doubleValue];

하지만 어떻게 스위프트 언어로 이걸 할 수 있을까요?

Swift 2 업데이트 보다 관용적이고 안전한 방법으로 이 작업을 수행할 수 있는 새로운 실패 가능한 이니셜라이저가 있습니다(많은 답변이 언급했듯이 NSString의 이중 값은 숫자가 아닌 값에 대해 0을 반환하기 때문에 매우 안전하지 않습니다).즉, 이 명령어는doubleValue"foo" ★★★★★★★★★★★★★★★★★」"0"★★★★★★★★★★★★★★★★)

let myDouble = Double(myString)

패스 같은 에는 입니다."foo"서 ''는doubleValue0이 가능한 는 0이 됩니다.nil 쓸 수 있어요.guard,if-let , 「」mapOptional<Double>

원본 투고: 승인된 답변과 같이 NSString 컨스트럭터를 사용할 필요가 없습니다.다음과 같이 간단히 브리지할 수 있습니다.

(swiftString as NSString).doubleValue

Swift 4.2+ 문자열에서 더블로

문자열 유형과 숫자 유형(Double, Float, Int) 간에 변환하려면 새 유형 이니셜라이저를 사용해야 합니다.옵션 타입(더블)이 반환됩니다.String이 숫자가 아닌 경우 올바른 값을 갖거나 0을 갖습니다.

주의: NSString doubleValue 속성은 값을 변환할 수 없는 경우(예: 잘못된 사용자 입력) 0을 반환하므로 권장되지 않습니다.

let lessPrecisePI = Float("3.14")

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

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

하려면 , 형식화된 숫자와 통화를 .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")

String을 더블 타입(및 통화)으로 변환하는 방법에 대한 자세한 내용은 블로그 투고를 참조하십시오.

【【Swift】【【Swift】를 하여, 더 스위프트한 느낌을】NSFormatter()NSString및 를 반환한다.nil에 ""가 되어 있지 않은 Double "test는 반환되지 )0.0를 참조해 주세요.

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

의 「Swift」를 합니다.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

또는 iflet 스테이트먼트를 사용합니다.

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문자열에 통화 기호가 포함되어 있는 통화를 사용하는 경우 포맷터에 표시됩니다.

서 또 하나의 을 '다음에'로 입니다.NSString:고고:고 、 :: 、 。

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

다음은 Swift 문자열에서 doubleValue()를 호출하여 더블백을 얻을 수 있는 확장 메서드입니다(예: 출력이 우선입니다).

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

에러 체크는 없지만, 필요에 따라서 추가할 수 있습니다.

1.부터는 Swift 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 ★★★★★★★★★★★★★★★★★」strtod0x16일:

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

찮 if면면 if.doubleValue', '행동', '행동', '행동', '행동'을 할 수 .CFString★★★★★★★★★★★★★★★★★★:

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

제가 찾던 답을 못 봤어요.누구라도 도움이 될까봐 내 글을 여기에 올렸어요이 답변은 특정 형식이 필요하지 않은 경우에만 유효합니다.

스위프트 3

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

Swift 2.0에서는 Objective-C 개발자처럼 생각하지 않는 것이 가장 좋습니다.따라서 "스트링을 이중으로 변환"하지 말고 "스트링에서 이중으로 초기화"해야 합니다.애플 문서: https://developer.apple.com/library/ios/ / documentation / Swift / Reference / Swift _ Double _ Structure / index . html # // apple _ ref / structr / Double / s : FSdcFMSdFSSQSd _

이것은 옵션의 init이므로, 제로 통합 연산자(--)를 사용하여 기본값을 설정할 수 있습니다.예:

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

SWIFT 3에서는 다음을 사용할 수 있습니다.

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

주의: - 문자열에 숫자 또는 로케일에 적합한 그룹 또는 십진수 구분 기호 이외의 문자가 포함되어 있는 경우 구문 해석은 실패합니다.- 문자열의 선행 또는 후행 공백 구분 문자는 무시됩니다.예를 들어 문자열 "5", "5" 및 "5"는 모두 숫자 5를 생성합니다.

매뉴얼에서 인용:https://developer.apple.com/reference/foundation/numberformatter/1408845-number

이것을 시험해 보세요.

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

메모

베타 5에서 삭제.이거 더 이상 안 돼요?

이것은 @yu의 대답에 기초하고 있다.

점을 구분자로 사용하는 나라에 있는 한 그의 솔루션은 훌륭합니다.로는 " " 입니다.NSNumberFormatter는 디바이스 로케일을 사용합니다.따라서 쉼표가 기본 구분 기호(France as@PeterK.mentioned 포함)로 사용되는 모든 국가에서 번호가 도트를 구분 기호로 사용하는 경우(일반적으로 해당)에 실패합니다. NS NS Number .US 포메터가 되므로 점을 구분자로 사용하여 선을 바꿉니다.

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

인 러러 an an an an an an an an가 됩니다.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
}

SWIFT 4

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

Swift 4.0

이거 먹어봐

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

스위프트 : 4 및 5

여기에는 다음 두 가지 방법이 있습니다.

  1. String -> Int -> Double:

    let strNumber = "314"
    if let intFromString = Int(strNumber){
        let dobleFromInt = Double(intFromString)
        print(dobleFromInt)
    }
    
  2. 문자열 -> NSString -> 더블

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

코드의 필요에 따라 원하는 대로 사용하세요.

놀이터에서 확인하세요!

let sString = "236.86"

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

그런데 내 X코드로

.toDouble() - 존재하지 않습니다.

.숫자 문자열이 아닌 값에서 값 0.0을 만듭니다...

이미 언급한 바와 같이 이를 실현하는 가장 좋은 방법은 직접 캐스팅입니다.

(myString as NSString).doubleValue

이를 통해 슬릭 네이티브 Swift String 확장을 만들 수 있습니다.

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

이를 통해 다음을 직접 사용할 수 있습니다.

myString.doubleValue

Apple이 Apple을 추가하는 doubleValue네이티브 String으로 확장자를 삭제하기만 하면 나머지 코드는 자동으로 컴파일 됩니다.

1.

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

2.

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

당신에게 도움이 될 수도 있어요.

내선번호(옵션 로케일

스위프트 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
        }
    }
}

SWIFT 3

클리어하기 위해서, 현재는 디폴트의 방법이 있습니다.

public init?(_ text: String)` of `Double` class.

모든 클래스에 사용할 수 있습니다.

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

,기타.

또는 다음을 수행할 수 있습니다.

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

StringEx 를 사용할 수 있습니다.연장하다String(「Dring-to-Number Conversion」 포함)toDouble().

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

문자열을 확인하고 이중으로 변환할 수 없는 경우 실패합니다.

예:

import StringEx

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

스위프트 4

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

기능하는 것:

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

「」를 사용합니다.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

로케일을 자동 검출하는 것은 문제가 없습니다.문자열 "Mon salaire est 999,999 €"의 프랑스어 로케일의 groupSeparator는 공백이 아닙니다.단, 공백과 동일하게 렌더링할 수 있습니다(여기서는 표시되지 않습니다).에 아래 thats가 없어도 정상적으로 동작합니다.!$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)

Swift 2.0에서 이 코드 사용

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

, 다음과 같은 ."27.8 °C","52.523553 kM" ★★★★★★★★★★★★★★★★★」"Total: 349.0".

이것은 Swift 4에서 동작합니다.

let anyString = "52.523553 kM"
let digitsCharacterSet = CharacterSet.init(charactersIn: "0123456789.")
let doubleResult = Double(anyString.components(separatedBy:digitsCharacterSet.inverted).joined())

조심해!여러 문자열에 대해 작동하지 않습니다.."27.8 °C 3.5 kM"

다음과 같이 String에 확장자를 추가하는 것이 더 읽기 쉽다고 생각합니다.

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

코드를 쓰면 됩니다.

myDouble = myString.doubleValue

내 문제는 쉼표였기 때문에 나는 다음과 같이 해결했다.

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

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

myString.doubleValue로 취득되는 CDouble 값을 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/24031621/swift-how-to-convert-string-to-double

반응형