为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕盖茨4494581 2021-11-25 16:43:12
到目前为止,我只能在每个 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") {              ...             }          }        })      }    }  });}
查看完整描述

2 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

您可以使用从 中获得的值进行递归调用getAdjacentCells。但是,请确保getAdjacentCells只为相同的id. 现在,当您重复相同的调用时,效率非常低。


另请参阅代码中的其他一些建议。


function isCellEmpty(adjacentCells) {

    // I would move this check here, although not necessary if you prefer it in the loop.

    if (typeof adjacentCells === "number") {

        $("#" + id).empty().append("<div>"); // You can chain jQuery...

        return;

    } 

    for (let id of adjacentCells) { // Just use a for..of loop

        if (id === null) continue; // keep IF-ELSE nesting flat.

        let cell = board[getBoardPosition(id)];

        if (cell.opened) continue; // Add this to avoid circling around

        cell.opened = true;

        isCellEmpty(getAdjacentCells(id)); // recursive call

    }

}

对象值

您在代码的注释中写道:


getAdjacentCells() 将返回类似于函数作为参数的对象数组或整数


但是,您在此答案下方的评论似乎表明情况并非(总是)。它可能是一个简单的对象,可以解释你为什么Object.values要迭代它。如果是这种情况,我会敦促进行更改,getAdjacentCells以便它确实返回一个数组。或者,如果这是不可能的,那么Object.values像你已经做过的那样使用:


function isCellEmpty(adjacentCells) {

    // I would move this check here, although not necessary if you prefer it in the loop.

    if (typeof adjacentCells === "number") {

        $("#" + id).empty().append("<div>"); // You can chain jQuery...

        return;

    } 

    for (let id of Object.values(adjacentCells)) { // Just use a for..of loop

        if (id === null) continue; // keep IF-ELSE nesting flat.

        let cell = board[getBoardPosition(id)];

        if (cell.opened) continue; // Add this to avoid circling around

        cell.opened = true;

        isCellEmpty(getAdjacentCells(id)); // recursive call

    }

}


查看完整回答
反对 回复 2021-11-25
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

递归在这里应该可以正常工作:在最基本的情况下,您可以使用id2. 但是,假设getAdjacentCells可能会返回您已经访问过的单元格,除非您能够跟踪已访问过的 ID 并将其传入,否则您最终将无限递归。


function setCellState(id, visited) {

  if(id === null) {

    return;

  }

  if(visited === undefined) {

    visited = new Set();

  }

  if(visited.has(id)) {

    return;

  }

  visited.add(id);


  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

  let adjacentCells = getAdjacentCells(id);

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

  if (typeof (adjacentCells) === "number") {

        // Removes all other divs, this prevents repetition

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

          // Appends an empty div

          .append("<div></div>");

  } else if (typeof (adjacentCells) === "object") {

    Object.values(adjacentCells).forEach(id2 => setCellState(id2, visited));

  }

我冒昧地更改了方法名称,以便更能代表该方法的实际作用。我还更改了它以从单个单元格的 ID 开始,因为这简化了递归并允许围绕 的行为进行注释getAdjacentCells以提供更好的上下文。


查看完整回答
反对 回复 2021-11-25
  • 2 回答
  • 0 关注
  • 165 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信