首页 > 解决方案 > 如何使此函数递归/运行,直到不满足要求?

问题描述

到目前为止,我只能在每个 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") {
              ... 
            }
          }
        })
      }
    }
  });
}

标签: javascriptrecursion

解决方案


您可以使用从中获得的值进行递归调用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
    }
}

推荐阅读