英文:
Recursive object construction
问题
任务:根据双败制度创建锦标赛赛程。对于上半区,没有问题,因为在第一轮获胜的队伍会在第二轮相遇,以此类推。但是对于下半区,除了第一轮败者之间的比赛,还需要添加在上半区第二轮中败者之间的比赛。
例如,给定一个下半区比赛的数组:
const games = [
{ id: 1, home_name: "Team 1", visitor_name: "Team 3", home_score: 1, visitor_score: 0, round: 2 },
{ id: 2, home_name: "Team 6", visitor_name: "Team 7", home_score: 1, visitor_score: 0, round: 2 },
{ id: 3, home_name: "Team 1", visitor_name: "Team 6", home_score: 0, visitor_score: 1, round: 3 },
{ id: 4, home_name: "Team 4", visitor_name: "Team 5", home_score: 1, visitor_score: 0, round: 3 },
{ id: 5, home_name: "Team 6", visitor_name: "Team 4", home_score: 1, visitor_score: 0, round: 4 },
];
要显示下半区的结构,您需要获取以下对象:
{
name: "Team 6",
children: [
{
name: "Team 4",
children: [{ name: "Team 4" }, { name: "Team 5" }],
},
{
name: "Team 6",
children: [
{ name: "Team 1", children: [{ name: "Team 1" }, { name: "Team 3" }] },
{ name: "Team 6", children: [{ name: "Team 6" }, { name: "Team 7" }] },
],
},
],
}
在父对象中,“Team 6”是下半区的冠军,这可以从最后一轮(第4轮)的比赛中得知,该轮比赛是在Team 4和Team 6之间进行的,而Team 4又是在第3轮比赛中由Team 4和Team 5之间的比赛决定的。
如何从比赛数组中获得这样的对象?比赛数量可能会根据队伍数量而变化。
英文:
Task: to create a tournament bracket according to the double elimination system. For the upper bracket, there were no problems, since the teams that won in the first round meet in the second, and so on. But for the lower bracket, in addition to the games among the losers in the first round, you need to add games among the losers in the second round of the upper bracket.
For example, given an array of lower bracket games:
const games = [
{ id: 1, home_name: "Team 1", visitor_name: "Team 3", home_score: 1, visitor_score: 0, round: 2 },
{ id: 2, home_name: "Team 6", visitor_name: "Team 7", home_score: 1, visitor_score: 0, round: 2 },
{ id: 3, home_name: "Team 1", visitor_name: "Team 6", home_score: 0, visitor_score: 1, round: 3 },
{ id: 4, home_name: "Team 4", visitor_name: "Team 5", home_score: 1, visitor_score: 0, round: 3 },
{ id: 5, home_name: "Team 6", visitor_name: "Team 4", home_score: 1, visitor_score: 0, round: 4 },
];
To display the structure of the lower bracket, you need to get the following object:
{
name: "Team 6",
children: [
{
name: "Team 4",
children: [{ name: "Team 4" }, { name: "Team 5" }],
},
{
name: "Team 6",
children: [
{ name: "Team 1", children: [{ name: "Team 1" }, { name: "Team 3" }] },
{ name: "Team 6", children: [{ name: "Team 6" }, { name: "Team 7" }] },
],
},
],
}
In the parent object "Team 6" is the winner of the lower bracket, this can be understood from the last (4) round played between Team 4 and Team 6, in turn Team 4 is determined by the game between Team 4 and Team 5 in round 3.
What the lower bracket will look like for these games:
How to get such an object from the games array? The number of games may vary depending on the number of teams.
答案1
得分: 2
你可以使用一个普通对象来收集以获胜队伍名称为键的子树,初始为空对象。然后按回合顺序迭代比赛,并从该对象中查找两支球队的子树(默认为 {name}
对象)。然后从中构造 children
属性,并将其包装成一个新的根节点。将该节点注册到子树集合中。
最后保留最后创建的对象,该对象将包含整个树:
function getTree(games) {
// 确保数据按回合排序 - 如果调用者已经确保了这一点,那么可以省略这个语句:
games = [...games].sort((a, b) => a.round - b.round);
const nodes = {}; // 这将按获胜队伍名称收集子树。
let winner;
for (const {home_name, home_score, visitor_name} of games) {
const name = home_score ? home_name : visitor_name;
winner = nodes[name] = {
name,
children: [
nodes[home_name] ?? { name: home_name },
nodes[visitor_name] ?? { name: visitor_name }
]
};
}
return winner;
}
const games = [
{ id: 1, home_name: "Team 1", visitor_name: "Team 3", home_score: 1, visitor_score: 0, round: 2 },
{ id: 2, home_name: "Team 6", visitor_name: "Team 7", home_score: 1, visitor_score: 0, round: 2 },
{ id: 3, home_name: "Team 1", visitor_name: "Team 6", home_score: 0, visitor_score: 1, round: 3 },
{ id: 4, home_name: "Team 4", visitor_name: "Team 5", home_score: 1, visitor_score: 0, round: 3 },
{ id: 5, home_name: "Team 6", visitor_name: "Team 4", home_score: 1, visitor_score: 0, round: 4 },
];
console.log(getTree(games));
英文:
You could use a plain object to collect subtrees keyed by the winning team's name, starting out with an empty object. Then iterate the games in order of round and look up the two team's subtrees from that object (with a default {name}
object). Then construct the children
property from that and wrap it into a new root node. Register that node in the collection of subtrees.
Finally retain the last object that was created which will have the whole tree:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function getTree(games) {
// Ensure the data is sorted by round -- if this is already ensured by caller, then you can drop this statement:
games = [...games].sort((a, b) => a.round - b.round);
const nodes = {}; // This will collect the subtrees, keyed by the winning team's name.
let winner;
for (const {home_name, home_score, visitor_name} of games) {
const name = home_score ? home_name : visitor_name;
winner = nodes[name] = {
name,
children: [
nodes[home_name] ?? { name: home_name },
nodes[visitor_name] ?? { name: visitor_name }
]
};
}
return winner;
}
const games = [
{ id: 1, home_name: "Team 1", visitor_name: "Team 3", home_score: 1, visitor_score: 0, round: 2 },
{ id: 2, home_name: "Team 6", visitor_name: "Team 7", home_score: 1, visitor_score: 0, round: 2 },
{ id: 3, home_name: "Team 1", visitor_name: "Team 6", home_score: 0, visitor_score: 1, round: 3 },
{ id: 4, home_name: "Team 4", visitor_name: "Team 5", home_score: 1, visitor_score: 0, round: 3 },
{ id: 5, home_name: "Team 6", visitor_name: "Team 4", home_score: 1, visitor_score: 0, round: 4 },
];
console.log(getTree(games));
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论