简体   繁体   English

以特定方式遍历嵌套对象

[英]Traverse nested object in a particular way

I need to traverse a tree in a way that I don't know how to do it. 我需要以一种我不知道该怎么做的方式来遍历一棵树。 I have an object that represents a tournament that have nested objects inside which are the matches to play. 我有一个代表比赛的对象,里面有嵌套的对象,这些对象是要玩的比赛。 So I have 7 objects in total, the first one represents the FINAL that have two children which are the SEMIFINALS that have two more children each that are the QUARTERFINALS. 因此,我总共有7个对象,第一个表示具有两个子级的FINAL,这是SEMIFINALS,另外还有两个子级,即QUARTERFINALS。 It looks like this: 看起来像这样:

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 } 
   } 
}

The players on the final and semifinals are undefined because we haven't played the quarterfinals yet. 决赛和准决赛的球员是不确定的,因为我们还没有打过八强。

Then I have a function that tells the computer who won the match so the player advances to the next round. 然后,我有一个函数告诉计算机谁赢得了比赛,因此玩家前进到下一轮。 Works fine. 工作正常。 And finally I have a function that returns me which is the next match to play that looks like this: 最后,我有一个函数返回我,这是下一场比赛,看起来像这样:

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

The function works but not in the way I want because it returns me all the games on the right side until one player reaches the final and then it returns me the players from the left side. 该功能有效,但不是按照我想要的方式工作,因为它使我返回右侧的所有游戏,直到一名选手进入决赛,然后从左侧使我返回玩家。

I would like that the function returns me the 4th quarterfinal first, then the 3rd quarterfinal, then the 2nd quarterfinal, then the 1st quarterfinal, then the second semifinal, then the first semifinal and, at the end, the final. 我希望函数先返回第4个四分之一决赛,然后是第3个四分之一决赛,然后是第2个四分之一决赛,然后是第1个四分之一决赛,然后是第二个半决赛,然后是第一个半决赛,最后是决赛。

If anyone knows how to do it I would appreciate any help! 如果有人知道该怎么做,我将不胜感激!

You could use this function, which has a separate recursion function for tracking the depth in the tree, and so deciding if a potential match is deeper in the tree than the one that was found so far. 您可以使用此函数,该函数具有一个单独的递归函数来跟踪树中的深度,从而确定树中的潜在匹配是否比迄今为止找到的更深。 This way you are sure to get a match that is deepest in the tree: 这样,您肯定会获得树中最深的匹配:

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

In the demo below, Mary and Ann could play the "right-side" semi-finals, but as there are still games to play in the quarter finals, the function will return one of those, and not the one for Mary and Ann: 在下面的演示中,Mary和Ann可以打“右侧”半决赛,但是由于在四分之一决赛中仍有比赛要玩,该函数将返回其中一个,而不是Mary和Ann的一个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM