1

I want the following code below, that it also solves math string expressions (/, +, -, and *).

array_sum(array_column(array_intersect_key($lines, array_flip($keys)), 2));

As it is right now, the code above ignores the math problems and sticks to the sum instead. For an example:

expenses|test-1|628
expenses|test-2|2348/2
expenses|test-3|379

With the code of arrays above, the sum will be 3355. The correct sum is 2181.

To fully understand the current code line please see this answer of my last question.

Community
  • 1
  • 1
Airikr
  • 6,258
  • 15
  • 59
  • 110

1 Answers1

0

This should work for you:

Just add this function to your code:

function calculateBasicMath($expression) {
    $expression = preg_replace("/[^0-9\+\-\*\/\.\,]/", "", $expression);

    while(preg_match("/(\d+)([\*\/])(\d+)/", $expression, $hM) || preg_match("/(\d+)([\+\-])(\d+)/", $expression, $lM)) {

        if(!empty($hM)) {

            switch($hM[2]){
                case "*":
                    $expression = str_replace("$hM[1]$hM[2]$hM[3]", $hM[1] * $hM[3], $expression);
                break;

                case "/":
                    $expression = str_replace("$hM[1]$hM[2]$hM[3]", $hM[1] / $hM[3], $expression);
                break;
            }

        } elseif(!empty($lM)) {

            switch($lM[2]){
                case "+":
                    $expression = str_replace("$lM[1]$lM[2]$lM[3]", $lM[1] + $lM[3], $expression);
                break;

                case "-":
                    $expression = str_replace("$lM[1]$lM[2]$lM[3]", $lM[1] - $lM[3], $expression);
                break;
            }

        } else {
            break;
        }

    }
    return $expression;
}

And then change your line from:

array_sum(array_column(array_intersect_key($lines, array_flip($keys)), 2));

to:

array_sum(array_map("calculateBasicMath", array_column(array_intersect_key($lines, array_flip($keys)), 2)));
        //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ See here

So that it basically calls this function for each value.

The function itself first replaces everything expect: [0-9]+-/*., with preg_replace(). Then it simply searches for basic math, e.g. X[+-*/]X. But where / and * has a higher precedence than + and -. And as long as it finds such a math expressions it calculates these and replace them.

Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • 1
    I just love your answers :) Many thanks! But It adds over 3 000 to the total sum now :/ – Airikr Jul 16 '15 at 17:11
  • @ErikEdgren What do you mean with it adds over 3k? Can you give me an example of your file (pastebin link) and say what you expect to get and what you get with my code. – Rizier123 Jul 16 '15 at 17:12
  • @ErikEdgren I don't really see through your changes and what they should do. E.g. Your return statement in your foreach loop will end the loop. – Rizier123 Jul 16 '15 at 17:53
  • 1
    @ErikEdgren Ah I think I got it. Since you had also like: `10.5` in your file I completely forgot about the dot, so my code deleted the dot and `10.5` -> `105`. Updated my answer, just copy the function again and it should work – Rizier123 Jul 16 '15 at 17:58
  • I'm using `return` because I will only print it once because of the detailed information table (total expenses/dept, total income, total amount of money after every expense, and so on). But not, after your edit, it prints the correct total sum! :D – Airikr Jul 16 '15 at 17:59
  • 1
    @ErikEdgren You're welcome. (BTW: You can replace: `foreach($keys AS $key) { if($isdate == 0) { return $lines[$key][2]; } else { return $lines[$key][2]; } }` just with: `if($isdate == 0) return $lines[$keys[0]][2]; else return $lines[$keys[0]][2];`, since the return will end the function; Also you can replace: `if(strpos($lines[$key][2], '+') !== false OR [...]) { echo do_maths($lines[$key][2]); } else { echo $lines[$key][2]; }` everything just with: `echo calculateBasicMath($lines[$key][2]);`) – Rizier123 Jul 16 '15 at 18:01
  • 1
    You're the king! I can't thank you enough :D The project I working on will be open source when it's finished (which is soon if I'm not too lazy) so if you want, you can play with the source code as much as you can :) – Airikr Jul 16 '15 at 18:07