首页 > 解决方案 > 递归 JavaScript 函数在使用相同参数多次调用时会出错

问题描述

我对 JavaScript 很陌生。我构建了一个递归函数,在给定特定数据集的情况下生成简单的基于模板的短语。下面概述了它的一个示例。该函数随机选择与类别对应的对象ctgNo。它遍历对象以获取其组件,然后为它们分配包含数组列表的相关变量。

这是对象:

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"]] },
  ],
};

对象的组件,如等mA_2vrb_better定义如下:

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"]];

等等

以上是我用来运行以下函数的数据集:

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);

该函数在第一次调用时运行良好。使用上例中的相同参数(例如“1”)多次调用它时会出现问题。在这种情况下,for-in 循环不会退出(就像在第一个实例中那样),而是开始进入嵌套对象,表明该对象rndObjVal包含来自前一个函数调用的数据。如何解决这个问题,以便每次使用相同的参数调用函数时,它都像第一次一样顺利运行?

旁注:如果我使用参数“1”和“3”运行函数两次,其中对象的属性相同,我不会收到错误消息。

其次,有没有办法以更好的方式改进代码,因为我没有听说过很多关于 eval() 的好消息。

标签: javascriptarraysobjecteval

解决方案


推荐阅读