Swift - Cách chuyển đổi Chuỗi thành Đôi


241

Tôi đang cố gắng viết một chương trình BMI bằng ngôn ngữ nhanh chóng. Và tôi đã gặp vấn đề này: làm thế nào để chuyển đổi Chuỗi thành Double?

Trong Objective-C, tôi có thể làm như thế này:

double myDouble = [myString doubleValue];

Nhưng làm thế nào tôi có thể đạt được điều này bằng ngôn ngữ Swift?


1
Điều này đã thay đổi trong Swift 2, hãy xem câu trả lời mới bằng cách sử dụng trình khởi tạo có sẵn Double () mới: stackoverflow.com/a/32850058/276626
Paul Solt

Câu trả lời:


205

Swift 4.2+ Chuỗi thành gấp đôi

Bạn nên sử dụng trình khởi tạo kiểu mới để chuyển đổi giữa Chuỗi và kiểu số (Double, Float, Int). Nó sẽ trả về một loại Tùy chọn (Double?) Sẽ có giá trị chính xác hoặc bằng 0 nếu Chuỗi không phải là số.

Lưu ý: Không nên sử dụng thuộc tính doubleValue NSString vì nó trả về 0 nếu giá trị không thể được chuyển đổi (nghĩa là: đầu vào của người dùng xấu).

let lessPrecisePI = Float("3.14")

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

Rút ra các giá trị để sử dụng chúng bằng 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!)")
}

Bạn có thể chuyển đổi số định dạng và tiền tệ bằng cách sử dụng NumberFormatterlớp.

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

Định dạng tiền tệ

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

Đọc thêm về bài đăng trên blog của tôi về việc chuyển đổi Chuỗi thành Loại kép (và tiền tệ) .


2
một vấn đề khác là nó không hỗ trợ các số ở các địa phương khác ngoài 1.000.00, nếu bạn sử dụng các định dạng khác như 1 000,00 thì cuối cùng sẽ cắt được 2 số thập phân. Ít nhất đây là những gì đang xảy ra cho Objective-C. - Theo tài liệu của Apple: (Chúng không nhận biết được miền địa phương) Các phương thức tiện lợi sau đây đều bỏ qua các ký tự khoảng trắng ban đầu (khoảng trắng) và bỏ qua các ký tự dấu. Họ không nhận thức được địa phương. NSScanner hoặc NSNumberFormatter có thể được sử dụng để phân tích cú pháp số mạnh hơn và nhận biết địa phương.
mskw

@mskw Tôi đã thêm chi tiết bổ sung về việc sử dụng NumberFormatter để phân tích tiền tệ. Trong mã của tôi, tôi sẽ kết hợp nhiều bộ định dạng cố gắng chuyển đổi bằng cú pháp if / let để tôi có thể phân tích cả hai số được định dạng tiền tệ ($ 1.000,00) hoặc số được định dạng (1.000). Bạn không phải lúc nào cũng biết người dùng sẽ nhập số như thế nào, vì vậy việc có thể hỗ trợ cả hai là lý tưởng với một nhóm các câu lệnh if / let.
Paul Solt

276

Swift 2 Cập nhật Có initializers failable mới cho phép bạn thực hiện điều này bằng cách thành ngữ và an toàn hơn (như nhiều câu trả lời đã lưu ý, giá trị gấp đôi NSString là không phải là rất an toàn vì nó sẽ trả về 0 cho các giá trị số không. Điều này có nghĩa rằng doubleValuecác "foo""0"là giống nhau.)

let myDouble = Double(myString)

Điều này trả về một tùy chọn, vì vậy trong các trường hợp như chuyển vào "foo"nơi doubleValueđã trả về 0, intializer sẽ có sẵn nil. Bạn có thể sử dụng một guard, if-lethoặc mapđể xử lýOptional<Double>

Bài đăng gốc: Bạn không cần sử dụng hàm tạo NSString như câu trả lời được chấp nhận đề xuất. Bạn có thể chỉ cần cầu nó như thế này:

(swiftString as NSString).doubleValue

5
ohai, Jarsen. Một nhược điểm của phương pháp này là nó sẽ không thất bại nếu chuỗi không phải là một cặp hợp lệ. Thay vào đó bạn sẽ chỉ nhận được 0,0. Đó là, kết quả của - [NSString doubleValue]Doublenhanh chóng khi được gọi là Double?( Optional<Double>). Điều này khác với hàm Swift String toInt()trả về Int?và tuyên bố trong các tài liệu rằng nó "... chấp nhận các chuỗi khớp với biểu thức chính quy" [- +]? [0-9] + "chỉ."
Derrick Hathaway

Có, sử dụng .toInt()sẽ tốt hơn. Tuy nhiên, đây không chỉ là câu trả lời cho cách thực hiện chính xác điều tương tự, mà là trong Swift.
Jarsen 3/2/2015

Cách tiếp cận này kết hợp chặt chẽ bạn với Foundation và có thể sẽ không hoạt động trên bất kỳ triển khai Swift nào của Apple.
Erik Kerber

5
Trong Swift 2.0 Double.init?(_ text: String)hiện có sẵn bộ khởi tạo.
mixel

3
Đây không phải là cách tiếp cận tốt nhất. Nó sẽ thất bại tùy thuộc vào dấu phân cách thập phân. Nó sẽ ổn với '.' nhưng không phải với ','. NSNumberFormatter sẽ hỗ trợ dấu tách thập phân được sử dụng trong nội địa hóa hiện tại.
Julian Król

75

Để có thêm một chút cảm giác Swift, sử dụng NSFormatter()tránh truyền tới NSStringvà trả về nilkhi chuỗi không chứa Doublegiá trị (ví dụ: "test" sẽ không trả về 0.0).

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

Ngoài ra, mở rộng loại Swift String:

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

và sử dụng nó như toInt():

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

Điều này trả về một tùy chọn Double?phải được mở ra.

Hoặc với việc hủy bỏ bắt buộc:

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

hoặc với một câu lệnh if let:

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

Cập nhật: Để bản địa hóa, rất dễ áp ​​dụng các ngôn ngữ cho NSFormatter như sau:

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

Cuối cùng, bạn có thể sử dụng NSNumberFormatterCurrencyStyletrên trình định dạng nếu bạn đang làm việc với các loại tiền tệ mà chuỗi chứa ký hiệu tiền tệ.


Tôi thích ý tưởng mở rộng lớp String cho các ứng dụng sẽ sử dụng nhiều nơi chuyển đổi. Nhưng tôi không thấy được lợi ích của sự phức tạp khi gọi NSNumberFormatter, vì việc chuyển sang NSString và sử dụng .doubleValue dường như ít nhất là trực tiếp, và dễ đọc và dễ nhớ hơn.
rõ ràng

12
Trên thực tế, lợi thế của việc sử dụng NSNumberFormatter () là phương thức numberFromString: sẽ trả về nil nếu chuỗi chứa các ký tự không tạo thành một số kép. Vấn đề với doubleValue trên NSString là nó sẽ luôn trả lại gấp đôi (ví dụ 0,0 cho "kiểm tra") bất kể. Vì vậy, nếu bạn đang xử lý tất cả các loại chuỗi và bạn muốn kiểm tra xem chuỗi đó có phải là một chuỗi không, không có ký tự bổ sung nào, sử dụng NSNumberFormatter là cách tốt nhất.
dirkgroten 10/2/2015

4
Điều này thất bại trên tiếng Pháp.
Peter K.

1
Đây là một giải pháp tuyệt vời, nhưng chỉ sử dụng mã này, nó sẽ không hoạt động ở các quốc gia nơi dấu phẩy được sử dụng làm dấu phân cách (bao gồm cả Pháp như @PeterK. Đã đề cập). Tôi đã thử viết một bình luận với giải pháp, nhưng nó quá dài nên tôi phải làm cho nó một câu trả lời thay thế. Ở đây bạn đi: Giải pháp sửa đổi
Jacob R

53

Một tùy chọn khác ở đây là chuyển đổi cái này thành một NSStringvà sử dụng cái đó:

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

13
Tôi ước có một cách tốt hơn để làm điều này. Làm thế nào tôi có thể biết nếu phân tích cú pháp thất bại, ví dụ.
Ryan Hoffman

2
@RyanHoffman Thật không may, hợp đồng doubleValue của NSString chưa bao giờ cung cấp bất kỳ điều nào trong số đó. Tất cả những gì bạn nhận được là 0,0 nếu chuỗi không bắt đầu bằng một đại diện hợp lệ của một số, HUGE_VAL và -HUGE_VAL khi tràn / tràn. Nếu bạn muốn biết lý do phân tích thất bại, tôi tin rằng bạn cần xem xét NSNumberFormatter, được thiết kế để xử lý chuyển đổi số / chuỗi theo cách mạnh mẽ hơn.
Jarsen

Vì có thể khó tìm thấy câu trả lời đó, nên đây là:(swiftString as NSString).doubleValue
LearnCocos2D

24

Đây là một phương thức mở rộng cho phép bạn chỉ cần gọi doubleValue () trên chuỗi Swift và lấy lại gấp đôi (ví dụ đầu ra là trước)

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

Đây là phương pháp mở rộng:

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

Không kiểm tra lỗi, nhưng bạn có thể thêm nó nếu bạn cần.


20

Kể từ Swift 1.1, bạn có thể trực tiếp chuyển Stringđến const char *tham số.

import Foundation

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

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

Nếu bạn không thích phản đối atof:

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

Một cảnh báo: hành vi chuyển đổi là khác nhau NSString.doubleValue.

atofstrtodchấp nhận 0xchuỗi hex có tiền tố:

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

Nếu bạn thích .doubleValuehành vi, chúng tôi vẫn có thể sử dụng CFStringbắc cầu:

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

Tôi là một fan hâm mộ của phương pháp này thay vì sử dụng NSString.
Sam Soffes

10

Trong Swift 2.0, cách tốt nhất là tránh suy nghĩ như một nhà phát triển Objective-C. Vì vậy, bạn không nên "chuyển đổi một chuỗi thành một đôi" mà bạn nên "khởi tạo một chuỗi từ một chuỗi". Tài liệu của Apple tại đây: https://developer.apple.com/l Library / iosd

Đây là một init tùy chọn để bạn có thể sử dụng toán tử hợp nhất nil (??) để đặt giá trị mặc định. Thí dụ:

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

Double.init?(_ text: String)trở nên khả dụng trong Swift 2.0. Bạn nên đề cập đến điều này. Các câu trả lời khác ở đây không phải vì mọi người nghĩ giống như các nhà phát triển Objective-C mà vì trình khởi tạo này không có sẵn trước đó.
mixel

Quả thực bạn đúng. Điều này chỉ có sẵn trong Swift 2.0, tôi sẽ đề cập đến nó :) Nhưng giống như trong các ngôn ngữ khác, bạn khởi tạo một loại với loại khác và không nên mong đợi một loại có thể chuyển đổi sang loại khác. Cuộc tranh luận kéo dài nhưng với tư cách là một nhà phát triển Obj-C, tôi có nhiều thực tiễn xấu khi mã hóa với Swift và đây là một trong số đó :)
Toom

10

Trên SWIFT 3 , bạn có thể sử dụng:

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

Lưu ý: - Nếu một chuỗi chứa bất kỳ ký tự nào ngoài các chữ số hoặc nhóm hoặc dấu phân cách thập phân phù hợp với miền địa phương, thì việc phân tích cú pháp sẽ thất bại. - Bất kỳ ký tự phân cách không gian hàng đầu hoặc dấu trong một chuỗi đều bị bỏ qua. Ví dụ: các chuỗi Trò chơi 5, 5, và 5, tất cả đều tạo ra số 5.

Lấy từ tài liệu: https://developer.apple.com/reference/foundation/numberformatter/1408845-number


10

Tôi chưa thấy câu trả lời mà tôi đang tìm kiếm. Tôi chỉ đăng ở đây của tôi trong trường hợp nó có thể giúp bất cứ ai. Câu trả lời này chỉ hợp lệ nếu bạn không cần một định dạng cụ thể .

Swift 3

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

9

Thử cái này:

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

GHI CHÚ

Đã xóa trong Beta 5. Điều này không còn hoạt động?


1
BridgeToObjectiveC () đã bị xóa trong Xcode 6 Beta 5. Phương pháp Mr Smiley là cách nhanh nhất tôi tìm thấy vào lúc này
faraquet99

7

Đây là dựa trên câu trả lời của @Ryu

Giải pháp của anh ấy thật tuyệt vời miễn là bạn đang ở một quốc gia nơi các dấu chấm được sử dụng làm dấu phân cách. Theo mặc định NSNumberFormattersử dụng ngôn ngữ thiết bị. Do đó, điều này sẽ thất bại ở tất cả các quốc gia nơi dấu phẩy được sử dụng làm dấu tách mặc định (bao gồm cả Pháp là @PeterK. Đã đề cập) nếu số này sử dụng dấu chấm làm dấu phân cách (thông thường là trường hợp). Để đặt ngôn ngữ của NSNumberFormatter này thành Hoa Kỳ và do đó sử dụng dấu chấm làm dấu phân cách thay thế dòng

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

với

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

Do đó, mã đầy đủ trở thành

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

Để sử dụng, chỉ cần gọi "Your text goes here".toDouble()

Điều này sẽ trả lại một tùy chọn Double?

Như @Ryu đã đề cập, bạn có thể buộc Unrap:

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

hoặc sử dụng một if lettuyên bố:

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

1
Đây là câu trả lời đúng. Phiên bản Swift 3 sẽ là NumberFormatter().number(from: myString)?.doubleValue
nicolas leo

7

Chuyển 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

thử cái này

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

6

Swift: 4 và 5

Có thể có hai cách để làm điều này:

  1. Chuỗi -> Int -> Double:

    let strNumber = "314"
    if let intFromString = Int(strNumber){
        let dobleFromInt = Double(intFromString)
        print(dobleFromInt)
    }
  2. Chuỗi -> NSString -> Đôi

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

Sử dụng nó dù sao bạn thích theo bạn cần mã.


Phương pháp đầu tiên không hiệu quả với tôi, tuy nhiên phương pháp thứ hai hoạt động khá tốt.
Saurabh

@Saurabh, bạn có thể giải thích rõ hơn về chuỗi của bạn là gì không?
Abhirajsinh Thakore

5

Vui lòng kiểm tra nó trên sân chơi!

let sString = "236.86"

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

Nhân tiện, trong Xcode của tôi

.toDouble () - không tồn tại

.doubleValue tạo giá trị 0,0 từ các chuỗi không phải là số ...


4

1.

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

2.

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

Có thể là sự giúp đỡ này cho bạn.


4

Như đã chỉ ra, cách tốt nhất để đạt được điều này là với việc đúc trực tiếp:

(myString as NSString).doubleValue

Xây dựng từ đó, bạn có thể tạo một tiện ích mở rộng Swift String nguyên bản:

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

Điều này cho phép bạn trực tiếp sử dụng:

myString.doubleValue

Mà sẽ thực hiện đúc cho bạn. Nếu Apple thêm doubleValuechuỗi vào chuỗi gốc, bạn chỉ cần xóa tiện ích mở rộng và phần còn lại của mã sẽ tự động biên dịch tốt!


Phương thức của Apple sẽ được gọi là .toDouble ... giống như toInt. Đó là một thiếu sót kỳ lạ. Có khả năng sẽ được chỉnh sửa trong phiên bản Swift trong tương lai. Tôi thích phương thức mở rộng nhất, giữ cho mã sạch sẽ.
n13

Giá trị trả về phải là gấp đôi KHÔNG phải là số nổi
Leo Dabus

4

Chuyển 3

Để xóa, ngày nay có một phương thức mặc định:

public init?(_ text: String)của Doublelớp.

Nó có thể được sử dụng cho tất cả các lớp.

let c = Double("-1.0") let f = Double("0x1c.6") let i = Double("inf") , Vân vân.


2

Gia hạn với miền địa phương tùy chọn

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
Tôi đã thêm ví dụ Swift 3.1. Ý bạn là gì bởi "... và thêm một ví dụ cho miền địa phương"? 🙂
imike

1

Hoặc bạn có thể làm:

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

1

Bạn có thể sử dụng StringEx . Nó mở rộng Stringvới các chuyển đổi chuỗi thành số bao gồm toDouble().

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

Nó xác minh chuỗi và không thành công nếu nó không thể được chuyển đổi thành gấp đôi.

Thí dụ:

import StringEx

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

1

Swift 4

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

0

Những gì cũng hoạt động:

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

LƯU Ý: 'scanDouble' không được dùng nữa trong iOS 13.0
uplearnedu.com

0

Sử dụng mã này trong Swift 2.0

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


0

Sử dụng Scannertrong một số trường hợp là một cách rất thuận tiện để trích xuất số từ một chuỗi. Và nó gần như mạnh mẽ như NumberFormatterkhi giải mã và xử lý các định dạng số và địa phương khác nhau. Nó có thể trích xuất số và tiền tệ với các dấu tách thập phân và nhóm khác nhau.

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

    }
}

Tuy nhiên, có những vấn đề với dấu phân cách có thể được hình thành dưới dạng phân cách từ.

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

Không có vấn đề để tự động phát hiện miền địa phương. Lưu ý rằng việc phân nhóm người dùng trong ngôn ngữ địa phương của Pháp trong chuỗi "Mon salaire est 9 999,99 €" không phải là một khoảng trắng, mặc dù nó có thể hiển thị chính xác như không gian (ở đây không có). Đó là lý do tại sao mã dưới đây hoạt động tốt mà không có !$0.isWhitespaceký tự được lọc ra.

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

Tôi thấy dễ đọc hơn để thêm phần mở rộng vào Chuỗi như sau:

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

và sau đó bạn chỉ có thể viết mã của bạn:

myDouble = myString.doubleValue

-1

vấn đề của tôi là dấu phẩy vì vậy tôi giải quyết nó theo cách này:

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

chúng ta có thể sử dụng giá trị CDouble mà myString.doubleValue thu được


Lỗi: 'Chuỗi' không có thành viên có tên 'doubleValue'
Matthew Knippen 23/07/14

@Matthew Có, không có thành viên nào được gọi là "giá trị kép", vì vậy chúng tôi có thể sử dụng Giá trị
CDouble

1
vi.wikipedia.org/wiki/ Từ Hãy tham khảo các số phức ở đó và đọc tài liệu tham khảo Swift .. Không có bất kỳ CDouble nào ... Bạn đang nói về Swift hay ngôn ngữ khác? Và tôi có nghĩa là nhanh chóng mà không có phần mở rộng?
Adrian Sluyters
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.