如何实现用户可以添加多个自定义if语句?
例如,假设存在一个名为x的给定变量,其给定值为let,即8。 用户看到x = 8并且有一个按钮来添加if语句。他单击按钮并可以插入触发事件的条件(假设它打印“Hello World”)。所以他将“x <100”输入到该字段中,这是真的。因此打印“Hello World”。 再次点击按钮后,他可以添加其他条件,让我们说“x <7”也是如此。因为两个条件都是真的,所以仍然会打印“Hello World”。 我觉得你的问题很明确,尽管我缺乏词汇量。 那么我怎么能设法让用户添加一个未定义的条件,在打印“Hello World”之前将检查这些条件? 我所知道的唯一解决方案是限制可能的条件数量,并检查每个条件是否为空/条件说明。
非常感谢!
答案 0 :(得分:4)
除非你想要构建一个完整的语言,否则你必须明白你将在这里允许的具体操作。
例如<
和>
以及==
的操作,基本上所有比较操作(<=
和>=
)都可以通过以下内容:
/* 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 */
你的&#34;硬&#34; job现在是将用户输入解释为某些condition
。但这并不太难,您只需要将"<"
的文本输入映射到实际的运算符<
。
您可以调整上述代码,以便轻松处理Double
而不是Int
,如果您需要的话。 但是你必须意识到浮点不准确以及检查平等时出现的问题(感谢@dfri指出这一点)。
关于将条件与or
而不是and
相结合,上面的代码所做的以及您当前在问题中描述的内容,有一点困难的部分。
仅仅因为我喜欢闭包:以下是整个输入读取和解析:
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"))
除了使用函数解析运算符之外,您甚至可以使用从">"
到(>)
等的普通旧字典映射。
答案 1 :(得分:1)
首先,您需要一种在运营商之间切换的方法。一个非常简单的enum
是完美的。只需添加您要使用的所有运算符。
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
值。
struct Condition {
var value: Int
var operation: Operator
}
此函数返回Bool
,具体取决于x
,inputValue
和所选operator
。
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
}
}
这是相同的但是对于一大堆条件。在这里,您可以实现更多逻辑。如果所有都需要为真,例如添加:if !result { return false }
。
func checkAllConditions(x:Int, conditions: [Condition]) {
for condition in conditions {
let result = checkCondition(x, condition: condition)
print(result)
}
}
现在您需要做的就是在用户创建数据时将条件存储在数组中
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])
答案 2 :(得分:1)
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
}
}
试验:
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