首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态评估用户添加的If-语句。

动态评估用户添加的If-语句。
EN

Stack Overflow用户
提问于 2016-01-02 13:43:52
回答 3查看 255关注 0票数 2

如何实现用户可以添加多个自定义if-语句?

例如,假设有一个给定变量x,它的给定值为8。用户看到x=8,并有一个按钮来添加if-语句。他单击按钮并插入触发事件的条件(假设它打印"Hello“)。所以他将"x < 100“输入到字段中,这是正确的。因此,“你好世界”是印刷。在再次单击按钮后,他可以添加另一个条件,比如"x < 7“,这也是正确的。因为这两个条件都是正确的,所以"Hello“仍然是打印出来的。我认为你明白我的问题所在,尽管我缺乏词汇量。那么,在打印"Hello“之前,我如何才能让用户添加一些未定义的条件,这些条件将被检查?我所知道的唯一解决方案是限制可能的条件数量,并检查每个条件是否为空/条件是什么。

非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-02 14:07:04

除非您想要构建一种完整的语言,否则您必须弄清楚您在这里将允许哪些确切的操作。

例如,<>==的操作,基本上所有比较操作(<=>= )都可以通过以下方式实现:

代码语言:javascript
复制
/* your X variable, might be var if you desire to change */
let x = 12

/* the array of conditions the user entered */
var conditions : [(((Int, Int) -> Bool), Int)] = []

/* some user input - read as e.g. "x > 2"*/
conditions.append((<, 100))
conditions.append((>, 2))
conditions.append((==, 12))

/* you evaluate all conditions in the following way */
let eval = conditions.map { $0(x, $1) }
let allTrue = !eval.contains(false)
/* allTrue would be true in this case because 12 < 100 && 12 > 2 && 12 == 12 */

您的“困难”工作是现在将用户输入解释为某些condition。但这并不太困难,您只需要将"<"的文本输入映射到实际的运算符<

如果您觉得需要的话,可以轻松地调整上面的代码来处理Double而不是Int,但是您必须意识到浮点不准确,以及在检查等式时出现的问题(感谢@dfri指出了这一点)。

更困难的部分是将条件与or而不是and结合起来,上面的代码做了什么,以及您目前在问题中描述了什么。

仅仅是因为我喜欢闭包:下面是整个输入、读取和解析:

代码语言:javascript
复制
func getOperator(str: String) -> ((Int, Int) -> Bool)? {
    switch str {
    case "<":
        return (<)
    case ">":
        return (>)
    case "==":
        return (==)
    case "<=":
        return (<=)
    case ">=":
        return (>=)
    default:
        return nil
    }
}

func parseUserInput(str:String) -> (((Int, Int) -> Bool), Int) {
    var input = str as NSString
    input = input.stringByReplacingOccurrencesOfString(" ", withString: "")
    //let variable = input.substringToIndex(1) // in case you want more than one variable, but that will have to change the entire setup a bit
    // this has to be this "ugly" to incorporate both 1 char and 2 char long operators
    let operato = input.substringFromIndex(1).stringByTrimmingCharactersInSet(NSCharacterSet.alphanumericCharacterSet())
    let number = input.substringFromIndex(operato.lengthOfBytesUsingEncoding(NSASCIIStringEncoding) + 1)

    if let number = Int(number), op = getOperator(operato) {
        return (op, number)
    }

    return ((<, 999999)) // need some error handling here
}

conditions.append(parseUserInput("x > 123"))

您甚至可以使用从">"(>)等简单的旧字典映射,而不是使用函数解析操作符。

票数 4
EN

Stack Overflow用户

发布于 2016-01-02 13:55:04

首先,您需要一种在操作符之间切换的方法。一个非常简单的enum非常适合这一点。只需添加所有要使用的操作符即可。

代码语言:javascript
复制
enum Operator : String {

    case biggerThan = ">"
    case smallerThan = "<"
    case equal = "=="

    init?(string:String) {
        switch string {
        case ">" :
            self = .biggerThan
        case "<" :
            self = .smallerThan
        case "==" :
            self = .equal
        default :
            return nil
        }
    }
}

每次用户单击一个按钮并插入一个条件时,都会创建相应的Condition值。

代码语言:javascript
复制
struct Condition {
    var value: Int
    var operation: Operator
}

此函数根据xinputValue和选择的operator返回一个operator

代码语言:javascript
复制
func checkCondition(x: Int, condition: Condition) -> Bool {
    switch condition.operation {
    case .biggerThan :
        return condition.value > x
    case .smallerThan :
        return condition.value < x
    case .equal :
        return condition.value == x
    }
}

这也是一样的,但在很多条件下。在这里您可以实现更多的逻辑。如果所有这些都需要为真,例如,add:if !result { return false }

代码语言:javascript
复制
func checkAllConditions(x:Int, conditions: [Condition]) {
    for condition in conditions {
        let result = checkCondition(x, condition: condition)
        print(result)
    }
}

现在,您所需要做的就是在用户创建条件时将条件存储在数组中。

代码语言:javascript
复制
func userCondition(operation:String, input:String) -> Condition? {

    guard let op = Operator(string: operation) else {
        return nil
    }
    guard let doubleValue = Double(input) else {
        return nil
    }

    return Condition(value: Int(doubleValue), operation: op)
}

let conditionA = userCondition("<", input: "10")! // use if let instead of !
let conditionB = userCondition(">", input: "10")! // use if let instead of !
let conditionC = userCondition("==", input: "23")! // use if let instead of !

var x : Int = 23

checkAllConditions(x, conditions: [conditionA,conditionB,conditionC])
票数 1
EN

Stack Overflow用户

发布于 2016-01-02 13:58:13

代码语言:javascript
复制
struct MyConditions {
    let myEps: Double = 0.001
    var x: Double
    var lessThan = [Double]()
    var equalTo = [Double]()
    var greaterThan = [Double]()

    init(x: Double) {
        self.x = x
    }

    mutating func addConstraint(operand: Double, op: String) {
        if op == "<" {
            lessThan.append(operand)
        }
        else if op == "==" {
            equalTo.append(operand)
        }
        else if op == ">" {
            greaterThan.append(operand)
        }
    }

    func checkConstraints() -> Bool {
        for op in lessThan {
            if !(x < op) {
                return false
            }
        }
        for op in equalTo {
            if !(x - myEps < op && x + myEps > op) {
                return false
            }
        }
        for op in greaterThan {
            if !(x > op) {
                return false
            }
        }
        return true
    }
}

测试:

代码语言:javascript
复制
func feasibleHelloWorld(x: MyConditions) {
    if x.checkConstraints() {
        print("Hello world!")
    }
}

var x = MyConditions(x: 8)
x.addConstraint(100, op: "<")
x.checkConstraints() // true
feasibleHelloWorld(x) // Hello world!

x.addConstraint(8, op: "==")
x.checkConstraints() // true
feasibleHelloWorld(x) // Hello world!

x.addConstraint(7, op: "<")
x.checkConstraints() // false
feasibleHelloWorld(x) // ... nothing
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34566538

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档