Swift - Convert values in array to doubles or floats
update: Xcode 8.3.2 • Swift 3.1
extension Collection where Iterator.Element == String {
var doubleArray: [Double] {
return flatMap{ Double($0) }
}
var floatArray: [Float] {
return flatMap{ Float($0) }
}
}
usage:
let strNumbersArray = ["1.5","2.3","3.7","4.5"] // ["1.5", "2.3", "3.7", "4.5"]
let doublesArray = strNumbersArray.doubleArray // [1.5, 2.3, 3.7, 4.5]
let floatsArray = strNumbersArray.floatArray // [1.5, 2.3, 3.7, 4.5]
let total = doublesArray.reduce(0, +) // 12
let average = total / Double(doublesArray.count) // 3
If you have an Array of Any? where you need to convert all strings from Optional Any to Double:
extension Collection where Iterator.Element == Any? {
var doubleArrayFromStrings: [Double] {
return flatMap{ Double($0 as? String ?? "") }
}
var floatArrayFromStrings: [Float] {
return flatMap{ Float($0 as? String ?? "") }
}
}
usage:
let strNumbersArray:[Any?] = ["1.5","2.3","3.7","4.5", nil] // [{Some "1.5"}, {Some "2.3"}, {Some "3.7"}, {Some "4.5"}, nil]
let doublesArray = strNumbersArray.doubleArrayFromStrings // [1.5, 2.3, 3.7, 4.5]
let floatsArray = strNumbersArray.floatArrayFromStrings // [1.5, 2.3, 3.7, 4.5]
let total = doublesArray.reduce(0, +) // 12
let average = total / Double(doublesArray.count) // 3
convert array of string into Double in swift
I will talk about convert an Array
of String
to Array
of Double
.
In swift Array
has a method called map
, this is responsable to map the value from array, example, in map function you will receive an object referent to your array, this will convert this object to your new array ex.
let arrOfStrings = ["0.3", "0.4", "0.6"];
let arrOfDoubles = arrOfStrings.map { (value) -> Double in
return Double(value)!
}
The result will be
UPDATE:
@LeoDabus comments an important tip, this example is considering an perfect datasource, but if you have a dynamic source you can put ?
on return and it will work, but this will return an array with nil
like that
let arrOfStrings = ["0.3", "0.4", "0.6", "a"];
let arrOfDoubles = arrOfStrings.map { (value) -> Double? in
return Double(value)
}
Look this, the return array has a nil
element
If you use the tips from @LeoDabus you will protect this case, but you need understand what do you need in your problem to choose the better option between map
or compactMap
example with compactMap
let arrOfStrings = ["0.3", "0.4", "0.6", "a"];
let arrOfDoubles = arrOfStrings.compactMap { (value) -> Double? in
return Double(value)
}
look the result
UPDATE:
After talk with the author (@davidandersson) of issue, this solution with map ou contactMap isn't his problem, I did a modification in his code and work nice.
first I replaced var message = "" per var rateValue:Double = 0.0 and replaced
Floatto
Double`
look the final code
let url = URL(string: "https://www.x-rates.com/calculator/?from=EUR&to=USD&amount=1")!
let request = NSMutableURLRequest(url : url)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
var rateValue:Double = 0.0;
if let error = error {
print(error)
} else {
if let unwrappedData = data {
let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)
var stringSeperator = "<span class=\"ccOutputRslt\">"
if let contentArray = dataString?.components(separatedBy: stringSeperator){
if contentArray.count > 0 {
stringSeperator = "<span"
let newContentArray = contentArray[1].components(separatedBy: stringSeperator)
if newContentArray.count > 0 {
rateValue = Double(newContentArray[0])! + 10
}
}
}
}
}
//
print("Rate is \(rateValue)"); //Rate is 11.167
}
task.resume()
Hope to help you
UInt32 array to Double array Swift
Use
UInt32TestArray.map { Double($0) }
to get an array of Double
.
Swift 4: Array for all types of Ints and Floating point numbers
If you want two different types in one array, why don't you use a union, e.g. using an enum
:
enum MyNumber {
case integer(Int)
case double(Double)
}
let numbers: [MyNumber] = [.integer(10), .double(2.0)]
However, in most situations it would be probably better to just convert all Int
into Double
and just have a [Double]
array.
iOS Swift: when sorting an array by value, where to convert string to float
Double
has an initializer that can take a StringProtocol
, though of course it returns an Optional
since the string may or may not actually be numbers. In order to sort your strings as doubles you'll need a fallback option in case it fails, or else you'll need to force unwrap these init
s if you can guarantee they'll always be doubles. The options look like this:
//Fallback using a nil-coalescing operator
OfferList.sort { (Double($0.Price) ?? 0) > (Double($1.Price) ?? 0) }
//Force unwrapping
OfferList.sort { Double($0.Price)! > Double($1.Price)! }
As a small, unrelated aside, it is considered best practice to name variables and attributes of objects in camel case, like offerList
and $0.price
. Not a requirement, of course, but this is what other Swift developers would be expecting.
How to convert pyramid type of String to array of doubles in Swift 4
You can use
components(separatedBy: .newlines)
to separate the string into
lines,map
to map the lines to the (outer) array,components(separatedBy: .whitespaces)
to separate each line into
separate numbers,compactMap(Double.init)
to convert the numbers in a line to the (inner) array ofDouble
(ignoring invalid floating point numbers).
Putting it together:
import Foundation
var sampleString = """
55
94 48
95 30 96
"""
let values = sampleString.components(separatedBy: .newlines).map {
$0.components(separatedBy: .whitespaces).compactMap(Double.init)
}
print(values) // [[55.0], [94.0, 48.0], [95.0, 30.0, 96.0]]
Swift - How to convert String to Double
Swift 4.2+ String to Double
You should use the new type initializers to convert between String and numeric types (Double, Float, Int). It'll return an Optional type (Double?) which will have the correct value or nil if the String was not a number.
Note: The NSString doubleValue property is not recommended because it returns 0 if the value cannot be converted (i.e.: bad user input).
let lessPrecisePI = Float("3.14")
let morePrecisePI = Double("3.1415926536")
let invalidNumber = Float("alphabet") // nil, not a valid number
Unwrap the values to use them using 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!)")
}
You can convert formatted numbers and currency using the NumberFormatter
class.
let formatter = NumberFormatter()
formatter.locale = Locale.current // USA: Locale(identifier: "en_US")
formatter.numberStyle = .decimal
let number = formatter.number(from: "9,999.99")
Currency formats
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")
Read more on my blog post about converting String to Double types (and currency).
How to turn an array of an array of doubles into string, Swift
From the description in your question it seems as if the argument of nestedFunction(...)
should be an array of arrays with double valued elements ([[Double]]
) rather than an array with double valued elements ([Double]
).
You can make use of .flatten()
to your simply nested array nestedArray
in nestedFunction(...)
, and thereafter e.g. reduce
to transform the Double
valued elements of the flattened array to one concenated String
.
var array1 = [2.6, 6.7, 7.2, 4.1, 3.1]
var array2 = [1.2, 3.5, 2.8, 4.5, 6.4]
var array3 = [1.2, 1.3, 1.4, 1.5, 1.6]
var nestedArray = [array1, array2, array3]
func nestedFunction (nestedArray: [[Double]])-> String {
return String(nestedArray
.flatten()
.reduce("") { $0 + ", " + String($1) }
.characters.dropFirst(2))
}
let asString = nestedFunction(nestedArray)
// asString = "2.6, 6.7, 7.2, 4.1, 3.1, 1.2, 3.5, 2.8, 4.5, 6.4, 1.2, 1.3, 1.4, 1.5, 1.6"
As an alternative, if you're set on using a for
loop, you can use for ... in
on the flattened array, e.g.:
var array1 = [2.6, 6.7, 7.2, 4.1, 3.1]
var array2 = [1.2, 3.5, 2.8, 4.5, 6.4]
var array3 = [1.2, 1.3, 1.4, 1.5, 1.6]
var nestedArray = [array1, array2, array3]
func nestedFunction (nestedArray: [[Double]])-> String {
var stringVar: String = ""
var isFirstElement = true
for elem in nestedArray.flatten() {
stringVar += (isFirstElement ? "" : ", ") + String(elem)
isFirstElement = false
}
return stringVar
}
let asString = nestedFunction(nestedArray)
// asString = "2.6, 6.7, 7.2, 4.1, 3.1, 1.2, 3.5, 2.8, 4.5, 6.4, 1.2, 1.3, 1.4, 1.5, 1.6"
Note that due to limited floating point precision, some double values might end up with a "messy" String
representation (e.g. 2.6
might end up as 2.6000000000000001
) when using the direct String
initializer (String($1)
and String(elem)
above, in the first and second method, respectively). To redeem this you could set a fixed number of fraction digits for the String
representation of your Double
values, using the following String
initializer:
String(format: "%.3f", myDoubleValue)
/* \
number of fraction digits (3 here) */
E.g., replace String($1)
and String(elem)
in the methods above by String(format: "%.3f", $1)
and String(format: "%.3f", elem)
, respectively, for some number of fraction digits of your choice. The Double
values will be rounded to the number of supplied fraction digits.
Is there a proper way to convert a Double to a Float in Swift?
guard let unwrappedAttitude = attitude else {
fatalError("attitude was nil!")
}
let roll = Float(unwrappedAttitude.roll)
let pitch = Float(unwrappedAttitude.pitch)
should be the way to go.
How can I convert data into types like Doubles, Ints and Strings in Swift?
Xcode 11 • Swift 5.1 or later
To convert from String
or any Numeric
type to Data
:
extension StringProtocol {
var data: Data { .init(utf8) }
}
extension Numeric {
var data: Data {
var source = self
// This will return 1 byte for 8-bit, 2 bytes for 16-bit, 4 bytes for 32-bit and 8 bytes for 64-bit binary integers. For floating point types it will return 4 bytes for single-precision, 8 bytes for double-precision and 16 bytes for extended precision.
return .init(bytes: &source, count: MemoryLayout<Self>.size)
}
}
To convert from Data
(bytes) back to String
extension DataProtocol {
var string: String? { String(bytes: self, encoding: .utf8) }
}
To convert from Data
back to generic Numeric
value
extension Numeric {
init<D: DataProtocol>(_ data: D) {
var value: Self = .zero
let size = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
assert(size == MemoryLayout.size(ofValue: value))
self = value
}
}
extension DataProtocol {
func value<N: Numeric>() -> N { .init(self) }
}
let value = 12.34 // implicit Double 12.34
let data = value.data // double data - 8 bytes
let double = Double(data) // implicit Double 12.34
let double1: Double = .init(data) // explicit Double 12.34
let double2: Double = data.value() // explicit Double 12.34
let double3 = data.value() as Double // casting to Double 12.34
Now we can easily add a property for each Numeric
type:
extension DataProtocol {
var integer: Int { value() }
var int32: Int32 { value() }
var float: Float { value() }
var cgFloat: CGFloat { value() }
var float80: Float80 { value() }
var double: Double { value() }
var decimal: Decimal { value() }
}
Playground testing
let intData = 1_234_567_890_123_456_789.data // 8 bytes (64 bit Integer)
let dataToInt: Int = intData.integer // 1234567890123456789
let intMinData = Int.min.data // 8 bytes (64 bit Integer)
let backToIntMin = intMinData.integer // -9223372036854775808
let intMaxData = Int.max.data // 8 bytes (64 bit Integer)
let backToIntMax = intMaxData.integer // 9223372036854775807
let myInt32Data = Int32(1_234_567_890).data // 4 bytes (32 bit Integer)
let backToInt32 = myInt32Data.int32 // 1234567890
let int32MinData = Int32.min.data // 4 bytes (32 bit Integer)
let backToInt32Min = int32MinData.int32 // -2147483648
let int32MaxData = Int32.max.data // 4 bytes (32 bit Integer)
let backToInt32Max = int32MaxData.int32 // 2147483647
let myFloatData = Float.pi.data // 4 bytes (32 bit single=precison FloatingPoint)
let backToFloat = myFloatData.float // 3.141593
backToFloat == .pi // true
let myCGFloatData = CGFloat.pi.data // 4 bytes (32 bit single=precison FloatingPoint)
let backToCGFloat = myCGFloatData.cgFloat // 3.141593
backToCGFloat == .pi // true
let myDoubleData = Double.pi.data // 8 bytes (64 bit double-precision FloatingPoint)
let backToDouble = myDoubleData.double // 3.141592653589793
backToDouble == .pi // true
let myFloat80Data = Float80.pi.data // 16 bytes (128 bit extended-precision FloatingPoint)
let backToFloat80 = myFloat80Data.float80 // 3.141592653589793116
backToFloat80 == .pi // true
let decimalData = Decimal.pi.data // 20 bytes Decimal type
let backToDecimal = decimalData.decimal // 3.14159265358979323846264338327950288419
backToDecimal == .pi // true
let stringBytes = "Hello World !!!".data.prefix(4) // 4 bytes
let backToString = stringBytes.string // "Hell"
Related Topics
String to Double in Xcode 6's Swift
Avplayer Not Full Screen in Landscape Mode Using iOS Swift
How to Convert Date (Without Knowing the Kind) to String
Swift - Could Not Cast Value of Type 'Uitabbarcontroller'
@Ibdesignable - View Not Rendering as Expected
Uidocumentinteractioncontroller() Swift
How to Set Cmutablepointer<Objcbool> to False in Swift
Firebase Dynamic Link Doesnt Work in Safari Swift
Show Posts from the Users You Are Following - Swift
What's Happening Behind the Scenes in Xctest's @Testable
Uiview Rounded Corner - Swift 2.0
Alpha for Background Color Not Working in iOS
How to Get the Today's and Tomorrow's Date in Swift 4