NSExpression Calculator in Swift
As already said in a comment, you have to call expressionValueWithObject()
on the expression:
let expr = NSExpression(format: equation)
if let result = expr.expressionValueWithObject(nil, context: nil) as? NSNumber {
let x = result.doubleValue
println(x)
} else {
println("failed")
}
Update for Swift 3:
let expr = NSExpression(format: equation)
if let result = expr.expressionValue(with: nil, context: nil) as? Double {
print(result) // -0.25
} else {
print("failed")
}
Details
- Xcode 9.4.1, Swift 4.1
- Xcode 10.2.1 (10E1001), Swift 5
Solution
import Foundation
extension String {
private func allNumsToDouble() -> String {
let symbolsCharSet = ".,"
let fullCharSet = "0123456789" + symbolsCharSet
var i = 0
var result = ""
var chars = Array(self)
while i < chars.count {
if fullCharSet.contains(chars[i]) {
var numString = String(chars[i])
i += 1
loop: while i < chars.count {
if fullCharSet.contains(chars[i]) {
numString += String(chars[i])
i += 1
} else {
break loop
}
}
if let num = Double(numString) {
result += "\(num)"
} else {
result += numString
}
} else {
result += String(chars[i])
i += 1
}
}
return result
}
func calculate() -> Double? {
let transformedString = allNumsToDouble()
let expr = NSExpression(format: transformedString)
return expr.expressionValue(with: nil, context: nil) as? Double
}
}
Usage
"3*(3-1)-5".calculate()
Full sample
func test(_ expressrion: String) {
if let num = expressrion.calculate() {
print("\(expressrion) = \(num)")
} else {
print("\(expressrion) = nil")
}
}
test("3*(3-1)-5")
test("5.2*(2-1.79)-5.1")
test("11/5")