我怎样才能使这个函数递归/运行,直到不满足要求?

到目前为止,我只能在每个 if 语句之后硬编码相同的代码段,只需要更改 getAdjacentCells(id) 的参数即可。我一直无法找到重复这部分的方法。我认为这可以递归完成,但我不知道该怎么做。


编辑:我最初输入 isCellEmpty 得到了一个对象数组:[{topLeft: null}, {topCenter: "cell-1-2"}, {topRight: "cell-1-3"}, {middleLeft: null}, {middleRight: "cell-2-3"}],当实际上是单个对象时:{topLeft: null, topCenter: "cell-1-2", topRight: "cell-1-3", middleLeft: null , middleRight: "cell-2-3"}


// Gets an object that looks like this: {topLeft: null, topCenter: "cell-1-2", topRight: "cell-1-3", middleLeft: null, middleRight: "cell-2-3"}

function isCellEmpty(adjacentCells) {

  Object.values(adjacentCells).forEach(id => {

    // Checks that the ids in stored in the object values do not equal null

    if (id !== null) {

      board[getBoardPosition(id)].opened = true;

      // getAdjacentCells() will return either an array of objects similar to the one the function takes as an argument or an integer

      // if getAdjacentCells(id) returns a number, add a div to the HTML element with that id

      if (typeof (getAdjacentCells(id)) === "number") {

        // Removes all other divs, this prevents repetition

        $("#" + id).empty();

        // Appends an empty div

        $("#" + id).append("<div></div>");

      // HERE'S WHERE IT STARTS: If getAdjacentCells(id) returns an object, do the same as above with every id in it

      } else if (typeof (getAdjacentCells(id)) === "object") {

        Object.values(getAdjacentCells(id)).forEach(id2 => {

          if (id2 !== null) {

            board[getBoardPosition(id2)].opened = true;

            if (typeof (getAdjacentCells(id2)) === "number") {

              $("#" + id2).empty();

              $("#" + id2).append("<div></div>");

            // HERE IT REPEATS: 

            } else if (typeof (getAdjacentCells(id2)) === "object") {

              ... 

            }

          }

        })

      }

    }

  });

}


慕盖茨4494581
浏览 166回答 2
2回答

MMMHUHU

您可以使用从 中获得的值进行递归调用getAdjacentCells。但是,请确保getAdjacentCells只为相同的id. 现在,当您重复相同的调用时,效率非常低。另请参阅代码中的其他一些建议。function isCellEmpty(adjacentCells) {&nbsp; &nbsp; // I would move this check here, although not necessary if you prefer it in the loop.&nbsp; &nbsp; if (typeof adjacentCells === "number") {&nbsp; &nbsp; &nbsp; &nbsp; $("#" + id).empty().append("<div>"); // You can chain jQuery...&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp;&nbsp; &nbsp; for (let id of adjacentCells) { // Just use a for..of loop&nbsp; &nbsp; &nbsp; &nbsp; if (id === null) continue; // keep IF-ELSE nesting flat.&nbsp; &nbsp; &nbsp; &nbsp; let cell = board[getBoardPosition(id)];&nbsp; &nbsp; &nbsp; &nbsp; if (cell.opened) continue; // Add this to avoid circling around&nbsp; &nbsp; &nbsp; &nbsp; cell.opened = true;&nbsp; &nbsp; &nbsp; &nbsp; isCellEmpty(getAdjacentCells(id)); // recursive call&nbsp; &nbsp; }}对象值您在代码的注释中写道:getAdjacentCells() 将返回类似于函数作为参数的对象数组或整数但是,您在此答案下方的评论似乎表明情况并非(总是)。它可能是一个简单的对象,可以解释你为什么Object.values要迭代它。如果是这种情况,我会敦促进行更改,getAdjacentCells以便它确实返回一个数组。或者,如果这是不可能的,那么Object.values像你已经做过的那样使用:function isCellEmpty(adjacentCells) {&nbsp; &nbsp; // I would move this check here, although not necessary if you prefer it in the loop.&nbsp; &nbsp; if (typeof adjacentCells === "number") {&nbsp; &nbsp; &nbsp; &nbsp; $("#" + id).empty().append("<div>"); // You can chain jQuery...&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp;&nbsp; &nbsp; for (let id of Object.values(adjacentCells)) { // Just use a for..of loop&nbsp; &nbsp; &nbsp; &nbsp; if (id === null) continue; // keep IF-ELSE nesting flat.&nbsp; &nbsp; &nbsp; &nbsp; let cell = board[getBoardPosition(id)];&nbsp; &nbsp; &nbsp; &nbsp; if (cell.opened) continue; // Add this to avoid circling around&nbsp; &nbsp; &nbsp; &nbsp; cell.opened = true;&nbsp; &nbsp; &nbsp; &nbsp; isCellEmpty(getAdjacentCells(id)); // recursive call&nbsp; &nbsp; }}

犯罪嫌疑人X

递归在这里应该可以正常工作:在最基本的情况下,您可以使用id2. 但是,假设getAdjacentCells可能会返回您已经访问过的单元格,除非您能够跟踪已访问过的 ID 并将其传入,否则您最终将无限递归。function setCellState(id, visited) {&nbsp; if(id === null) {&nbsp; &nbsp; return;&nbsp; }&nbsp; if(visited === undefined) {&nbsp; &nbsp; visited = new Set();&nbsp; }&nbsp; if(visited.has(id)) {&nbsp; &nbsp; return;&nbsp; }&nbsp; visited.add(id);&nbsp; board[getBoardPosition(id)].opened = true;&nbsp; // getAdjacentCells() will return either an array of objects similar to the one the function takes as an argument or an integer&nbsp; let adjacentCells = getAdjacentCells(id);&nbsp; // if getAdjacentCells(id) returns a number, add a div to the HTML element with that id&nbsp; if (typeof (adjacentCells) === "number") {&nbsp; &nbsp; &nbsp; &nbsp; // Removes all other divs, this prevents repetition&nbsp; &nbsp; &nbsp; &nbsp; $("#" + id).empty()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Appends an empty div&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .append("<div></div>");&nbsp; } else if (typeof (adjacentCells) === "object") {&nbsp; &nbsp; Object.values(adjacentCells).forEach(id2 => setCellState(id2, visited));&nbsp; }我冒昧地更改了方法名称,以便更能代表该方法的实际作用。我还更改了它以从单个单元格的 ID 开始,因为这简化了递归并允许围绕 的行为进行注释getAdjacentCells以提供更好的上下文。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript