9

iOS で条件式を解きたい:

データベースから取得した方程式は NSString 形式です。たとえば、次のようになります。

if((height > 0), (weight+ 2 ), ( weight-1 ) )

私たちの理解によると、上記の文字列と別のheight>0条件を解析すると、NSString形式になります。しかし、それを評価するには、文字列を条件文に変換するにはどうすればよいでしょうか?

条件文が得られたら、次のように三項方程式に変換して方程式を解くことができます。

Bool status;

NSString *condition=@” height>0”;

If(condition)    //But condition is treated as a string and not as a conditional statement.
{
    status=True;
}
else
{
    status=False;
}

Return status ? weight+ 2 : weight-1;`

また、方程式は動的に変化する可能性があるため、ハードコーディングすることはできません。要するに、 として得られるこの方程式をどのように解くのですかNSString

お待ちいただいてありがとうございます!

4

2 に答える 2

5

DDMathParser の作成者はこちら...

Jonathan's answerを拡張するために、DDMathParser で完全に行う方法を次に示します。ただし、文字列をそのまま解析するには、2 つのことを行う必要があります。

ifまず、関数を作成する必要があります。

DDMathEvaluator *evaluator = [DDMathEvaluator sharedMathEvaluator];
[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError *__autoreleasing *error) {
    if ([args count] == 3) {
        DDExpression *condition = [args objectAtIndex:0];
        DDExpression *resultExpression = nil;
        NSNumber *conditionValue = [condition evaluateWithSubstitutions:vars evaluator:eval error:error];
        if ([conditionValue boolValue] == YES) {
            resultExpression = [args objectAtIndex:1];
        } else {
            resultExpression = [args objectAtIndex:2];
        }
        NSNumber *result = [resultExpression evaluateWithSubstitutions:vars evaluator:eval error:error];
        return [DDExpression numberExpressionWithNumber:result];
    }
    return nil;

} forName:@"if"];

これにより、if()3 つのパラメーターを受け取る関数が作成されます。最初のパラメーターがどのように評価されるかに応じて、2 番目または 3 番目のパラメーターの結果に評価されます。

もう 1 つ必要なことは、評価者に何heightweight意味するかを伝えることです。文字で始まらないため、$変数ではなく関数として解釈されます。で始まる場合は$、次のように評価するのと同じくらい簡単です。

NSString *expression = @"if(($height > 0), ($weight+ 2 ), ( $weight-1 ) )";
NSDictionary *variables = @{@"height" : @42, @"weight" : @13};
NSNumber *result = [expression evaluateWithSubstitutions:variables evaluator:evaluator error:nil];

ただし、これらはa で始まらない$ため、関数です。つまり、関数の評価結果をエバリュエーターに伝える必要があります。の場合と同様に、heightとの両方に関数を作成することで、これを行うことができます。weightif

[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError **error) {
    return [DDExpression numberExpressionWithNumber:@42];
} forName:@"height"];

または、もう少し動的にして のfunctionResolverブロックを使用することもできますDDMathEvaluator。これは、ブロック (woooooo) を返すブロックであり、次のようになります。

NSDictionary *values = @{@"height": @42, @"weight": @13};
[evaluator setFunctionResolver:^DDMathFunction(NSString *name) {
    DDMathFunction f = ^(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError **error) {
        NSNumber *n = [values objectForKey:name];
        if (!n) { n = @0; }
        return [DDExpression numberExpressionWithNumber:n];
    };
    return f;
}];

これらの 2 つの部分 (およびの値を登録ifして提供する) があれば、次のことができます。heightweight

NSString *expression = @"if((height > 0), (weight+ 2 ), ( weight-1 ) )";
NSNumber *result = [expression evaluateWithSubstitutions:nil evaluator:evaluator error:nil];

...そして の適切な結果を返します@15

(不明な関数が提供された変数値にフォールバックできるようにする計画がDDMathParserありますが、まだ完全には完了していません)

于 2013-05-17T05:36:09.423 に答える
4

独自のインタープリターを作成するか、この種の式をサポートするインタープリターを見つける必要があります。

最初の部分 (条件) は によって評価できますNSPredicate。2 番目の部分 (計算) では、数式の評価が必要になります。https://github.com/davedelong/DDMAthParserを試してみてください。多分あなたは両方を行うことができますがDDMathParser、私にはわかりません。

于 2013-05-16T10:39:11.037 に答える