Home > Mobile >  How can I evaluate an expression string containing variables?
How can I evaluate an expression string containing variables?

Time:08-07

In Unity I'm trying to make it so you enter an expression and then it outputs a value but I want to use variables like:

x = 10
"x   x * 10"

^ outputs 200

CodePudding user response:

You will need to create a Mathematical expression evaluator. This is essentially an algorithm to tokenize your input string and then evaluate every single token. Just search for "Mathematical expression evaluator in c# " and you'll find what you need.Because this is a quite large project on its own, it might make sense to use a library for that. Here are some libraries:

Math-Expression-evaluator

Matheval

CodePudding user response:

If you feel more adventurous you could even write your own évaluator using a parser library. This will allow specific behaviors if needed. Some libraries are :

CodePudding user response:

You can try and old trick with DataTable: we create a datatable with columns as variables, put their values into row and finally create a column with expression:

Code:

using System.Data;

...

public static T Eval<T>(string formula,
                        params (string name, object value)[] variables) {
  using DataTable table = new();

  foreach (var (n, v) in variables)
    table.Columns.Add(n, v is null ? typeof(object) : v.GetType());

  table.Rows.Add();

  foreach (var (n, v) in variables)
    table.Rows[0][n] = v;

  table.Columns.Add("__Result", typeof(double)).Expression = 
    formula ?? throw new ArgumentNullException(nameof(formula)); 

  return (T)(Convert.ChangeType(table.Compute($"Min(__Result)", null), typeof(T)));
}

Demo: (Please, fiddle yourself)

// 110
int result = Eval<int>("x   x * 10", ("x", 10));

More demos:

using System.Linq;

...

var vars = new (string name, object value)[] {
  ("x", 10),
  ("y", 5),
  ("z", 3),
};
      
var formulae = new string[] {
  "x   x * 10",
  "x   y * z",
  "1   2 * x * (x   y)",
  "123",
  "x / y   z",
};
      
var report = string.Join(Environment.NewLine, formulae
  .Select(formula => $"{formula,20} = {Eval<int>(formula, vars),5}"));
      
Console.WriteLine(report);

Output:

          x   x * 10 =   110
           x   y * z =    25
 1   2 * x * (x   y) =   301
                 123 =   123
           x / y   z =     5
  • Related