aki aki - 1 month ago 8
PHP Question

Parse array of logical strings into another human readable object

I'm trying to parse an array into logical structure using recursive function and so far, only close encounters.

This is what i receive:

[
"1921",
"AND",
"(",
"1923",
"OR",
"(",
"1925",
"AND",
"1924",
")",
")"
]


And this is what i must obtain:

{
terms: ["1921", {
terms: ["1923", {
terms: ["1925", "1924"],
operator: "AND"
}],
operator: "OR"
}],
operator: "AND"
}


Any help appreciated!

Answer

I'd approach it as a state machine which stores the current index and recursively iterates over the array item by item.

class StateMachine {
    protected $index = 0;
    protected $data;

    public function __construct($data) {
        $this->data = $data;
    }

    public function getTree() {
        return $this->parse($this->data);
    }

    protected function parse() {
        $result = ["terms" => []];
        while ($this->index < count($this->data)) {
            switch($this->data[$this->index]) { 
                case "(": 
                    $this->index++;
                    $result["terms"][] = $this->parse();
                    break;
                case ")":
                    $this->index++;
                    return $result;
                    break;
                case "AND":
                    $result["operator"] = "AND";
                    $this->index++;
                    break;
                case "OR":
                    $result["operator"] = "OR";
                    $this->index++;
                    break;
                default:
                    $result["terms"][] = $this->data[$this->index];
                    $this->index++;
                    break;
            }
        }
        return $result;
    }
}

$array = [
    "1921",
    "AND",
    "(",
    "1923",
    "OR",
    "(",
    "1925",
    "AND",
    "1924",
    ")",
    ")"
];

$machine = new StateMachine($array);
print json_encode($machine->getTree());

And you'll get exactly what you need.

Rewriting this to a recursive function would require using a global variable, but the principle will be similar.