Recursive JavaScript function gives error when called more than once with same parameter

Viewed 41

I am quite new to JavaScript. I built a recursive function to generate simple template-based phrases given a specific dataset. A sample of it is outlined below. The function randomly selects an object corresponding to the category ctgNo. It loops over the object to get its components and then assigns them with the related variables containing lists of arrays.

This is the object:

const ctg_ptr = {
  1: [
    { S: [["mA_2", "vrb_better", "pro_your", "N_1"]] },
  ],
  2: [
    { S: [["mA", "vrb_give", "H", "adj", "N", "prep"]] },
    { S: [["mA", "vrb2_2", "H", "adj", "N", "prep"]] },
  ],
  3: [
    { S: [["mA_2", "vrb_better", "pro_your", "N_1"]] },
  ],
};

The components of the object such as mA_2, vrb_better etc. are defined like this:

const vrb_better = [["running"], ["jumping"]];
const mA_2 = [["This morning"], ["That afternoon"]];
const pro_your = [["with your dog"]];
const N_1 = [["in the park"], ["in the street"]];

etc.

The above is the dataset I use to run the following function:

function partPhrase(ctgNo) {
  let start = "S";
  let expansion = [];
  let rules = {};
  debugger;
  let rndObjVal =
    ctg_ptr[ctgNo][
      Math.floor(
        Math.random() * (Object.values(ctg_ptr[ctgNo]).length - 1 - 0 + 1) + 0
      )
    ];

//this is the loop where the error happens

  for (let key in rndObjVal) {
    split = rndObjVal[key];
    for (let i in split) {
      for (let j in split[i]) {
        ary = split[i][j];
        rndObjVal[ary] = eval(ary);
      }
    }
  }

  rules = rndObjVal;

  console.log(rules);

  let result = expand(start, expansion);

  function expand(start, expansion) {
    if (rules[start]) {
      let pick = rules[start][Math.floor(Math.random() * rules[start].length)];
      for (let i = 0; i < pick.length; i++) {
        expand(pick[i], expansion);
      }
    } else {
      expansion.push(start);
    }
    return expansion.join(" ");
  }
  return result;
}

let phr_1 = partPhrase(1);
let phr_2 = partPhrase(1);

The function runs fine the first time it is invoked. The issue arises when calling it multiple times using the same parameter such as "1" in the example above. In that case the for-in loop would not exit (as it does in the first instance) rather it starts going into the nested object, indicating that the object rndObjVal contains data from the previous function call. How can this be fixed so that every time the function is called with the same parameters it runs as smoothly as it does the first time?

Side note: I do not get the error if I run the function twice with parameters "1" and "3", where the properties of the objects are identical.

Secondly, is there a way of improving the code in a better way since I haven’t heard many good things about eval().

0 Answers
Related