Swift - Convert Values in Array to Doubles or Floats

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 return example

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

Second example

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

compactMap example 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 replacedFloattoDouble`

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 inits 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 of Double (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



Leave a reply



Submit