Swift - Resolving a Math Operation in a String

Convert String to operator - swift

try something like this

var s = " 1 + 9 X 8"
s = s.replacingOccurrences(of: "X", with: "*")
let expn = NSExpression(format:s)
print("\(expn.expressionValue(with: nil, context: nil) ?? 0)")

Swift string task

This is a quick implementation: it handles expressions with 2 integer values and a single operator, where the operator is +, -, *, or /. The expressions look like <value> <operator> <value> = <value>. The values on the left-hand side of the expression are integers, but the value on the right-hand side can be a floating point value. (eg try? checkTask(task: "7 / 2 = 3.5") will print OK)

I think it can be a good starting point if you want to do something more advanced.

enum Error: Swift.Error {
case malformed
}
func checkTask(task: String) throws -> String {
let operations = "*/+-"
let split = task.replacingOccurrences(of: " ", with: "").split(separator: "=")
guard let resultString = split.last,
let expressionString = split.first else {
throw Error.malformed
}
let expression = expressionString.split { character in
operations.contains(character)
}

guard let operationString = expressionString.first(where: { operation in operations.contains(operation) }),
let lhsString = expression.first,
let rhsString = expression.last,
let equationResult = Double(String(resultString)),
let lhs = Double(lhsString),
let rhs = Double(rhsString) else {
throw Error.malformed
}

var operation: (Double, Double) -> Double
switch operationString {
case "+":
operation = (+)
case "-":
operation = (-)
case "*":
operation = (*)
case "/":
operation = (/)
default:
throw Error.malformed
}
let result = operation(lhs, rhs)
guard result == equationResult else {
return "Correct answer: \(result)"
}
return "OK"
}
let tasks = ["11 + 14 = 25", "2 + 2 = 5"]
let first = try? checkTask(task: tasks.first!) // "OK"
let second = try? checkTask(task: tasks.last!) // "Correct answer: 4.0"

If you want an error with a description you'll have to make the modifications yourself.

Convert Equation String to Int

Try it this way:

var equation = "\(8+3*4/5-1*(5+5))"  //"0"

And this way you can convert it to Int

var answer = equation.toInt()  // 0

Or you can directly do it this way:

var equation = 8+3*4/5-1*(5+5)   // 0

And As Martin R suggested if you want to do math operation in a string you can do it this way:

let expn = NSExpression(format:"8+3*4/5-1*(5+5)")
println(expn.expressionValueWithObject(nil, context: nil)) //"0"

Which will result as String but you can convert it to Int as I suggested above.

Here is original link for math operation in a string: Swift - Resolving a math operation in a string

Swift: Compute equation within String and convert to Int

You're looking for an arithmetic expression evaluator, which isn't trivial to do and there doesn't exist a simple function that just does it. You can try to find an open-source implementation of a simple one.

EDIT: Have a look at the Arithmetic Evaluation Rosetta Code page, which is the simplest thing you probably want. There isn't a Swift version (yet), but you should be able to do it yourself by looking at the other languages.

Another EDIT: Check out this Code Golf Thread which features some of the shortest arithmetic expression evaluators in some languages (no Swift yet)

Last EDIT: Also have a look at the Shunting-yard algorithm and generalised Operator-precedence parsing. I'm actually very attempted now to write a simple one in Swift...

Post last EDIT: There exists a Swift library for that :D. Also: Downvotes are for non-useful answers (see hover text), not for when there's a better answer (see comments)

Swift string formula into a real calculation

Xcode 8.3.1 • Swift 3.1

extension String {
var expression: NSExpression {
return NSExpression(format: self)
}
}

let a = 5
let b = 2
let intDictionary = ["a": a,"b": b]

var formula = "a * b"
if let timesResult = formula.expression.expressionValue(with: intDictionary, context: nil) as? Int {
print(timesResult) // 10
}
formula = "(a + b) / 2"
if let intAvgResult = formula.expression.expressionValue(with: intDictionary, context: nil) as? Int {
print(intAvgResult) // 3
}



let x = 5.0
let y = 2.0
let z = 3.0

let doubleDictionary = ["x": x, "y": y, "z": z]


formula = "(x + y + z) / 3"
if let doubleAvgResult = formula.expression.expressionValue(with: doubleDictionary, context: nil) as? Double {
print(doubleAvgResult)
}


Related Topics



Leave a reply



Submit