Home > Software design >  Recursive method to calculate the Boolean value of an array
Recursive method to calculate the Boolean value of an array

Time:02-21

I'm working on a Laravel/php app and I have this array where I want to collect the final result:

[
    {
        "nodeType": "or",
        "0": {
            "nodeType": "and",
            "0": {
                "nodeType": "and",
                "1": true,
                "2": false
            },
            "3": true
        },
        "2": {
            "nodeType": "or",
            "4": false,
            "5": true
        }
    }
]

I would like to be able to collect the final value which is either True or False. The array itself could contain any number of children, for example:

[
    {
        "nodeType": "or",
        "0": {
            "nodeType": "and",
            "0": {
                "nodeType": "or",
                "0": {
                    "nodeType": "and",
                    "1": true,
                    "2": false
                },
                "3": true
            },
            "3": true
        },
        "2": {
            "nodeType": "or",
            "4": false,
            "5": true
        }
    }
]

What would be the best way to go around this? I think loops don't work since the depth of the array is not fixed.

Edit 1: to answer some of the questions in the comments. The keys have no importance. the nodes has always two values. But a value could have its two values as in the second example. The outer level is an array but this array has only one entry. So it can simply be used as array[0] to get to the json object.

Edit 2: The result for the following array should be false but the first answer returns true.

{
    "nodeType": "and",
    "0": {
        "nodeType": "and",
        "0": {
            "nodeType": "and",
            "1": true,
            "2": false
        },
        "3": true
    },
    "2": {
        "nodeType": "or",
        "4": false,
        "5": true
    }
}

The nodetype can be either and or or. It is not always as written in the examples above.

CodePudding user response:

You could use a recursive function, like this:

function deduct($expr) {
    if (is_bool($expr)) return $expr; // Base case
    // If OR, we can stop when we find true (and return true). 
    // If AND, we can stop when we find false (and return false).
    $search = $expr["nodeType"] == "or";
    foreach ($expr as $key => $value) {
        if ($key !== "nodeType" && deduct($value) === $search) return $search;
    }
    // If that never happened, return the opposite (false for OR, true for AND)
    return !$search;
}

Example call using your second JSON as input:

$json = '[{"nodeType": "or","0": {"nodeType": "and", "0": {"nodeType": "or", "0": {"nodeType": "and","1": true,"2": false},"3": true},"3": true},"2": {"nodeType": "or","4": false,"5": true}}]';
$obj = json_decode($json, true)[0]; // The outer level is an array: unwrap it.
var_dump(deduct($obj));

Output:

bool(true)
  • Related