dart

using a string in a math equation in Dart


I store various formulas in Postgres and I want to use those formulas in my code. It would look something like this:

var amount = 100;
var formula = '5/105'; // normally something I would fetch from Postgres
var total = amount * formula; // should return 4.76

Is there a way to evaluate the string in this manner?


Solution

  • As far as I'm aware, there isn't a formula solver package developed for Dart yet. (If one exists or gets created after this post, we can edit it into the answer.)

    EDIT: Mattia in the comments points out the math_expressions package, which looks pretty robust and easy to use.

    There is a way to execute arbitrary Dart code as a string, but it has several problems. A] It's very roundabout and convoluted; B] it becomes a massive security issue; and C] it only works if the Dart is compiled in JIT mode (so in Flutter this means it will only work in debug builds, not release builds).

    So the answer is that unfortunately, you will have to implement it yourself. The good news is that, for simple 4-function arithmetic, this is pretty straight-forward, and you can follow a tutorial on writing a calculator app like this one to see how it's done.

    Of course, if all your formulas only contain two terms with an operator between them like in your example snippet, it becomes even easier. You can do the whole thing in just a few lines of code:

    void main() {
      final amount = 100;
      final formula = '5/105';
    
      final pattern = RegExp(r'(\d+)([\/+*-])(\d+)');
      final match = pattern.firstMatch(formula);
      final value = process(num.parse(match[1]), match[2], num.parse(match[3]));
    
      final total = amount * value;
      print(total); // Prints: 4.761904761904762
    }
    
    num process(num a, String operator, num b) {
      switch (operator) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
      }
    
      throw ArgumentError(operator);
    }