动态评估用户添加的If-Statements [英] Evaluate dynamically user-added If-Statements

查看:64
本文介绍了动态评估用户添加的If-Statements的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I achieve that users can add multiply custom if-statements?

例如,假设有一个名为x的给定变量,其给定值为let 8.
用户看到x = 8并且有一个按钮来添加if语句。他单击按钮并可以插入触发事件的条件(假设它打印Hello World)。所以他将x <100输入到该字段中,这是真的。因此打印Hello World。
再次点击按钮后,他可以添加其他条件,让我们说x< 7也是如此。因为两个条件都是真的,所以仍然会打印Hello World。
我认为即使我缺乏词汇量,你也明白了我的问题。
那么我怎么能设法让用户添加一个未定义的条件,在打印Hello World之前将检查这些条件?
我知道的唯一解决方案是限制可能的条件数量并检查每个条件是否为空/条件说明。

For example let's say there is a given variable called x with a given value of let's say 8. The user sees that x = 8 and has a button to add an if-statement. He clicks the button and can insert the condition which triggers an event (let's say it prints "Hello World"). So he enters "x < 100" into the field which is true. Therefore "Hello World" is printed. After clicking the button once again, he is able to add an other condition, let's say "x < 7" which is also true. Because both conditions are true, "Hello World" is still printed. I think you got the point of my questions, even though I lack the vocabulary. So how could I manage to let user add an undefined amount of conditions which will be checked before "Hello World" is printed? The only solution I know is to limit the possible amount of conditions and check each one if it is empty / what the conditions says.

非常感谢!

推荐答案

除非你想要构建一个完整的语言,否则你必须明白你将在这里允许的具体操作。

Unless you want to build an entire language you have to get clear on what exact operations you are going to allow here.

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

For example the operation of < and > and ==, basically all comparison operations (<= and >= as well) can be implemented via the following:

/* 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 */

现在你的硬工作是将用户输入解释为某些条件。但这并不太难,你只需要将<的文本输入映射到实际的运算符<

Your "hard" job is it now to interpret the user input as some condition. But that is not too difficult, you simply need a mapping of the text input of "<" to the actual operator <.

您可以调整上述代码来处理 Double 而不是 Int 如果你堕落就像你需要的那样容易。 但是你必须意识到浮点不准确以及检查平等时出现的问题(感谢@dfri指出这一点)。

You can adjust the above code to take care of Double instead of Int easily if you fell like you need that. But you have to aware of floating point inaccuracy and the problem that arise when checking for equality (thanks to @dfri for pointing this out).

关于将条件与组合而不是和以上代码的作用以及您目前在问题中描述的内容。

A little bit more difficult part comes in regards to combining the conditions with or instead of and what above code does and what you currently describe in your question.

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

Just because I like closures: The following is the entire input reading and parsing:

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"))

除了使用函数解析运算符,您甚至可以使用普通的dicti从>(>)等的映射

Instead of resolving the operator using a function you can even use a plain old dictionary mapping from ">" to (>) etc.

这篇关于动态评估用户添加的If-Statements的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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