Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>DDMathParser author here...</p> <p>To expand on <a href="https://stackoverflow.com/a/16585241/115730">Jonathan's answer</a>, here's how you could do it entirely in DDMathParser. However, to parse the string as-is, you'll need to do two things.</p> <p>First, you'll need to create an <code>if</code> function:</p> <pre><code>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"]; </code></pre> <p>This creates the <code>if()</code> function, which takes three parameters. Depending on how the first parameter evaluates, it either evaluates to the result of the second or third parameter.</p> <p>The other thing you'll need to do is tell the evaluator what <code>height</code> and <code>weight</code> mean. Since they don't start with a <code>$</code> character, they get interpreted as functions, and not variables. If they started with a <code>$</code>, then it would be as simple as evaluating it like this:</p> <pre><code>NSString *expression = @"if(($height &gt; 0), ($weight+ 2 ), ( $weight-1 ) )"; NSDictionary *variables = @{@"height" : @42, @"weight" : @13}; NSNumber *result = [expression evaluateWithSubstitutions:variables evaluator:evaluator error:nil]; </code></pre> <p>However, since they <em>don't</em> start with a <code>$</code>, they're functions, which means you need to tell the evaluator what the functions evaluate to. You could do this by creating functions for both <code>height</code> and <code>weight</code>, just like you did for <code>if</code>:</p> <pre><code>[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError **error) { return [DDExpression numberExpressionWithNumber:@42]; } forName:@"height"]; </code></pre> <p>Alternatively, you could make it a bit more dynamic and use the <code>functionResolver</code> block of <code>DDMathEvaluator</code>, which is a block that returns a block (woooooo) and would look like this:</p> <pre><code>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; }]; </code></pre> <p>With those two pieces in place (registering <code>if</code> and providing the values of <code>height</code> and <code>weight</code>), you can do:</p> <pre><code>NSString *expression = @"if((height &gt; 0), (weight+ 2 ), ( weight-1 ) )"; NSNumber *result = [expression evaluateWithSubstitutions:nil evaluator:evaluator error:nil]; </code></pre> <p>... and get back the proper result of <code>@15</code>.</p> <p>(I have plans to make <code>DDMathParser</code> allow unknown functions to fall back to provided variable values, but I haven't quite finished it yet)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload