Home > Blockchain >  Recursively solve terms in JSON with N possibilities
Recursively solve terms in JSON with N possibilities

Time:12-09

I have an input that is a JSON with this structure:

const logicJson2 = [
        [
            { "key": true  },
            "OR",
            { "key": true  }
        ],
        "AND",
        [
            { "key": false},
            "OR",
            { "key": true  }
        ]
]

This is an example, the input could be more complex, for example:

 const logicJson = [
            [
                  [
                    { "key": false  },
                    "AND",
                    { "key": true  }
                  ],
                  "OR",
                  { "key": true  }
            ],
            "AND",
            [
                { "key": false},
                "OR",
                { "key": true  }
            ]
    ]

I came up with the idea of using recursion to start solving it. So, if the input term is an array I pass it recursively to the function. This is a very simple example I start working on:

const store = new Map();
function analyze(term){
  if(Array.isArray(term[0])){
      store.set("first",{first: analyze(term[0])});
  }else{
      store.set("first",{first: term[0].key});
  }
  if(Array.isArray(term[2])){
    store.set("second",{second: analyze(term[2])});
  }else{
      store.set("second",{second: term[2].key});
  }

  if(store['first'] && store['second']){
    switch(term[1]){
      case 'AND':
        return term[0].key && term[2].key
        break;
      case 'OR':
        return term[0].key || term[2].key
        break;
    }
  }
}

Im stucked there and how should I approach this, and what would be the most efficient way of doing it?. Should store the results from the end, and start solving each term until I get the final result?, which has to be true or false depending on the logic. Is there an example or pattern out there should I consult?. Thanks a lot

CodePudding user response:

There is no need for a Map, as you need to stored values within the same function execution, so you can just use local variables for storing the return values from recursive calls. Secondly, you can simplify by checking the type of the argument itself, instead of the entry at index 0 and index 2. This way you avoid code duplication (for left and right operands).

Here is how it could be done:

const operators = {
    "OR": (a, b) => a || b,
    "AND": (a, b) => a && b
};

function evaluate(expression) {
    if ("key" in expression) return expression.key; // base case
    const [left, operator, right] = expression;
    return operators[operator](evaluate(left), evaluate(right));
}

// Demo
const expression = [
    [
        [{ "key": false  }, "AND", { "key": true  }],
        "OR",
        { "key": true  }
    ],
    "AND",
    [
        { "key": false},
        "OR",
        { "key": true  }
    ]
];

console.log(evaluate(expression));

  • Related