0

I need to filter some $data array with multiple conditions.

My code:

public static function filterTable(array $data, $conditions) : array {
    $data = array_filter($data, function ($row) use ($conditions) {
        if ($row["check_id"] == 0) {
            var_dump(['$row'=> $row], self::validateData($row, $conditions, null, 0));
            die();
        }
        return self::validateData($row, $conditions, null, 0);
    });

    return $data;
}

public static function validateData($row, $conditions, $res, $i) : bool {
    if ($res !== null) {
        $tempRes = self::compare($row[$conditions[$i]["column"]], $conditions[$i]["value"], $conditions[$i]["condition"]);
        $res = self::logicalOp($res, $tempRes, $conditions[$i-1]["operator"]);
    } else {
        $res = self::compare($row[$conditions[$i]["column"]], $conditions[$i]["value"], $conditions[$i]["condition"]);
    }
    if (!empty($conditions[$i]["operator"])) {
        self::validateData($row, $conditions, $res, ++$i);
    }

    if ($row["check_id"] == 0) {
        var_dump(["validateDataFunc" => $row, $res]);
        die();
    }
    return $res;
}

public static function logicalOp($val1, $val2, string $op) {
    switch ($op) {
        case "||":
            return ($val1 || $val2);
        case "&&":
            return ($val1 && $val2);
        default:
            return true;
    }
}

public static function compare($val1, $val2, string $op) : bool {
    switch ($op) {
        case "=":
            return $val1 == $val2;
        case "!=":
            return $val1 != $val2;
        case ">=":
            return $val1 >= $val2;
        case "<=":
            return $val1 <= $val2;
        case ">":
            return $val1 > $val2;
        case "<":
            return $val1 < $val2;
        default:
            return true;
    }
}

If you output the result of the function via var_dump in the validateData function, then the return value is false (which is what you want). But, if you display the result of calling the function itself (in filterTable function), you get true at the output.

Please note that I display the result of execution for the same array element.

Result into validateData function:

array(2) {
  ["validateDataFunc"]=>
  array(16) {}
  [0]=>
  bool(false)
}

Result into filterTable function:

array(1) {
  ["$row"]=>
  array(16) {}
}
bool(true)

I hope you'll give me some tips on how to improve my code.
Help me if u can do this, maybe I have too stupid mistake:)

Thanks

SOLUTION:

Add return to recursive call

public static function validateData($row, $conditions, $res, $i) : bool {
        if ($res !== null) {
            $tempRes = self::compare($row[$conditions[$i]["column"]], $conditions[$i]["value"], $conditions[$i]["condition"]);
            $res = self::logicalOp($res, $tempRes, $conditions[$i-1]["operator"]);
        } else {
            $res = self::compare($row[$conditions[$i]["column"]], $conditions[$i]["value"], $conditions[$i]["condition"]);
        }
        if (!empty($conditions[$i]["operator"])) {
            return self::validateData($row, $conditions, $res, ++$i); //here
        }
        return $res;
    }
kAsper
  • 1
  • 4
  • When you call `validateData()` recursively, you don't do anything with that result. So you're always returning the result of the original `self::compare()`, ignoring the result of the recursive call. – Barmar Sep 14 '22 at 20:43
  • Change that to `$res = self::validateData(...)` or just `return self::validateData(...)` – Barmar Sep 14 '22 at 20:45
  • @Barmar, I am passing the result as one of the arguments of the ```validateData()``` – kAsper Sep 14 '22 at 20:46
  • You're not passing it by reference, so assignment to it in the function doesn't change it. – Barmar Sep 14 '22 at 20:46
  • @Barmar thanks, it helped me. If u have time can u explain more about this case or tell me how to google it to read more? – kAsper Sep 14 '22 at 20:54
  • The question I linked to above doesn't explain it? – Barmar Sep 14 '22 at 20:55
  • @Barmar it explains how to solve the problem, but I cant catch the logic of how it works generally. I'll explain: when I called ```var_dump``` before returning the result, the value I needed was displayed, but when I got it where I needed it, the value was the opposite. And now, when I try to understand, I can’t see the essence of why it didn’t work, although I passed the result as an argument and then worked with it. Thank you very much for the decision, but I want to have a clear understanding of my actions)) – kAsper Sep 14 '22 at 21:12
  • You're dumping different `$res` variables. One is in the current function, the other is in the recursive function. – Barmar Sep 14 '22 at 21:16

0 Answers0