以特定方式遍历嵌套对象

时间:2016-11-13 17:04:16

标签: javascript tree

我需要以一种我不知道如何去做的方式遍历一棵树。我有一个对象代表一个锦标赛,其中有嵌套对象,其中包含要播放的匹配项。所以我总共有7个对象,第一个代表有两个孩子的FINAL,这两个孩子是SEMIFINALS,每个孩子有两个孩子,每个孩子都是QUARTERFINALS。它看起来像这样:

Match {
  player1: undefined,
  player2: undefined,
  childrenLeft: 
   Match {
     player1: undefined,
     player2: undefined,
     childrenLeft: 
      Match {
        player1: 'John',
        player2: 'Luke',
        childrenLeft: undefined,
        childrenRight: undefined },
     childrenRight: 
      Match {
        player1: 'Ann',
        player2: 'Mark',
        childrenLeft: undefined,
        childrenRight: undefined } },
  childrenRight: 
   Match {
     player1: undefined,
     player2: undefined,
     childrenLeft: 
      Match {
        player1: 'George',
        player2: 'Mary',
        childrenLeft: undefined,
        childrenRight: undefined },
     childrenRight: 
      Match {
        player1: 'Sofie',
        player2: 'Tom',
        childrenLeft: undefined,
        childrenRight: undefined } 
   } 
}

决赛和半决赛的球员都没有定义,因为我们还没有参加四分之一决赛。

然后我有一个功能告诉计算机谁赢了比赛,所以玩家前进到下一轮。工作良好。最后我有一个函数返回我,这是下一个匹配的游戏,如下所示:

Match.prototype.nextMatch = function () {
if (this.player1 && this.player2) return this;
if (!this.player2 && this.childrenRight !== undefined) return this.childrenRight.nextMatch();
if (!this.player1 && this.childrenLeft !== undefined) return this.childrenLeft.nextMatch();
}

这个功能有效,但不是我想要的方式,因为它让我回到了右边的所有比赛,直到一个玩家到达决赛,然后它从左侧返回我的球员。

我希望这个功能首先让我回到第四个四分之一决赛,然后是第四个四分之一决赛,然后是第二个四分之一决赛,然后是第一个四分之一决赛,然后是第二个半决赛,然后是第一个半决赛,最后是决赛。 / p>

如果有人知道怎么做,我将不胜感激任何帮助!

1 个答案:

答案 0 :(得分:0)

你可以使用这个函数,它有一个单独的递归函数来跟踪树中的深度,因此决定树中的潜在匹配是否比目前找到的更深。这样你肯定会得到树中最深的匹配:

Match.prototype.nextMatch = function () {
    var next, nextDepth = -1;

    (function recurse(match, depth = 0) {
        if (match.player1 && match.player2 && depth > nextDepth) {
            next = match;
            nextDepth = depth;
        }
        if (!match.player1 && match.childrenLeft)
            recurse(match.childrenLeft, depth + 1);
        if (!match.player2 && match.childrenRight) 
            recurse(match.childrenRight, depth + 1);
    })(this);
    return next;
}

在下面的演示中,Mary和Ann可以参加“右侧”半决赛,但由于在四分之一决赛中仍然有比赛,该功能将返回其中一个,而不是Mary的一个和安:

function Match(p1, p2) {
    this.player1 = p1;
    this.player2 = p2;
    this.childrenLeft = undefined;
    this.childrenRight = undefined;
}

Match.prototype.nextMatch = function () {
    var next, nextDepth = -1;
    
    (function recurse(match, depth = 0) {
        if (match.player1 && match.player2 && depth > nextDepth) {
            next = match;
            nextDepth = depth;
        }
        if (!match.player2 && match.childrenRight) 
            recurse(match.childrenRight, depth + 1);
        if (!match.player1 && match.childrenLeft)
            recurse(match.childrenLeft, depth + 1);
    })(this);
    return next;
}

var root = new Match();
root.childrenRight = new Match('Mary', 'Ann');
root.childrenLeft = new Match();
root.childrenLeft.childrenLeft = new Match('George', 'Mary'); 
root.childrenLeft.childrenRight = new Match('Sophie', 'Tom'); 

var nextMatch = root.nextMatch();

console.log('Next match: ', nextMatch.player1, nextMatch.player2);