我可以以某种方式强制NSExpression和expressionValue假定为Doubles而不是Ints吗? [英] Can I force NSExpression and expressionValue to assume Doubles instead of Ints somehow?

查看:120
本文介绍了我可以以某种方式强制NSExpression和expressionValue假定为Doubles而不是Ints吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从字符串中进行数学运算.

I'm trying to do math from a string.

当我使用NSExpression将字符串转换为数学问题,然后使用expressionValue获得结果时,Swift假定我想要一个Integer.考虑以下两个Playground示例:

When I turn a string into a math problem with NSExpression, and then get the result with expressionValue, Swift assumes I want an Integer. Consider these two Playground examples:

let currentCalculation = "10 / 6"
let currentExpression = NSExpression(format: currentCalculation)
print(currentExpression) // 10 / 6
if let result = currentExpression.expressionValue(with: nil, context: nil) as? Double {
    print(result) // 1
}

let anotherCalculation = "10.0 / 6.0"
let anotherExpression = NSExpression(format: anotherCalculation)
print(anotherExpression) // 10 / 6
if let result = anotherExpression.expressionValue(with: nil, context: nil) as? Double {
    print(result) // 1.666666667
}

我应该怎么做才能使我始终获得双倍成绩?我不想提前解析字符串.

What should I be doing so that I always get a Double as a result? I don't want to have to parse the string ahead of time.

第二个示例将"anotherExpression"转换为Integers,但结果仍然返回Double,这很有趣.

Pretty interesting that the second example turns "anotherExpression" into Integers, yet still returns a Double as a result.

推荐答案

使用第3方表达式解析器/计算器可能会更好, 例如 DDMathParser . NSExpression相当有限,并且没有强制浮起的选项 点评估.

You might be better off using a 3rd party expression parser/evaluator, such as DDMathParser. NSExpression is quite limited, and has no options to force floating point evaluation.

如果您想要(或必须)坚持使用NSExpression:这是(递归)替换所有常量的一种可能的解决方案 表达式中的值通过其浮点值:

If you want to (or have to) stick to NSExpression: Here is a possible solution to (recursively) replace all constant values in an expression by their floating point value:

extension NSExpression {

    func toFloatingPoint() -> NSExpression {
        switch expressionType {
        case .constantValue:
            if let value = constantValue as? NSNumber {
                return NSExpression(forConstantValue: NSNumber(value: value.doubleValue))
            }
        case .function:
           let newArgs = arguments.map { $0.map { $0.toFloatingPoint() } }
           return NSExpression(forFunction: operand, selectorName: function, arguments: newArgs)
        case .conditional:
           return NSExpression(forConditional: predicate, trueExpression: self.true.toFloatingPoint(), falseExpression: self.false.toFloatingPoint())
        case .unionSet:
            return NSExpression(forUnionSet: left.toFloatingPoint(), with: right.toFloatingPoint())
        case .intersectSet:
            return NSExpression(forIntersectSet: left.toFloatingPoint(), with: right.toFloatingPoint())
        case .minusSet:
            return NSExpression(forMinusSet: left.toFloatingPoint(), with: right.toFloatingPoint())
        case .subquery:
            if let subQuery = collection as? NSExpression {
                return NSExpression(forSubquery: subQuery.toFloatingPoint(), usingIteratorVariable: variable, predicate: predicate)
            }
        case .aggregate:
            if let subExpressions = collection as? [NSExpression] {
                return NSExpression(forAggregate: subExpressions.map { $0.toFloatingPoint() })
            }
        case .anyKey:
            fatalError("anyKey not yet implemented")
        case .block:
            fatalError("block not yet implemented")
        case .evaluatedObject, .variable, .keyPath:
            break // Nothing to do here
        }
        return self
    }
}

示例:

let expression = NSExpression(format: "10/6+3/4")
if let result = expression.toFloatingPoint().expressionValue(with: nil, context: nil) as? Double {
    print("result:", result) // 2.41666666666667
}

这适用于使用算术运算符和函数的简单"表达式以及某些高级"表达式类型(联合,交点等).如有必要,可以添加其余的转化.

This works with "simple" expressions using arithmetic operators and functions and some "advanced" expression types (unions, intersections, ...). The remaining conversions can be added if necessary.

这篇关于我可以以某种方式强制NSExpression和expressionValue假定为Doubles而不是Ints吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆