我正在读"Eloquent JavaScript“这本书,我对机器人项目的开始有一个问题。
function buildGrpah(edges) {
let graph = Object.create(null);
function addEdge(from, to) {
if (graph[from] == null) {
graph[from] = [to];
} else {
graph[from].push(to);
}
}
for (let [from, to] of edges.map(r => r.split("-"))) {
addEdge(from, to); addEdge(to, from);
}
return graph;
};
我理解主要原理,但我不明白为什么我们要在循环中两次调用addEdge
函数。你能给我解释一下吗?
发布于 2021-07-24 01:35:40
您可能会发现"from“和"to”变量的用法有点混乱。它们在第二次调用中将值切换到addEdge。我试着解释一下..
buildGraph获取位置对的列表。位置对只是意味着这两个位置有直接连接。
addEdge返回一个具有与位置对中提到的唯一位置相同数量的属性的对象。每个属性对应于一个唯一的位置,其值是属性键位置所连接到的所有其他位置的列表。
简而言之,addEdge被调用两次是因为它首先将位置对中的第一个值视为"from“或原始位置(addEdge返回的对象属性键),然后将第二个位置添加到其直接连接的位置列表中,然后将第二个位置视为原始位置,并将第一个位置添加到其可到达位置列表中。
问题是,位置对意味着第一个位置可以从第二个位置访问,反之亦然-因此在返回的对象中-您希望值对中的两个位置都有自己的条目作为addEdge返回对象中的属性键,然后它们需要在自己的可到达点列表中拥有彼此。伪装的例子:
location pair: "red_house - blue_house"
addEdges return object:
{
red_house: [blue_house],
blue_house: [red_house]
}
看到一个位置对如何做两件事了吗?它将blue_house设置为可从red_house访问,并将red_house设置为可从blue_house访问。这对应于如何调用add Edge两次-在调用之间颠倒参数。
在编程时有许多方法可以做同样的事情,作者可以选择让for...of循环只调用addEdge一次,然后在addEdge中处理切换和加倍执行,但您可以假设他认为在这种情况下for...of循环中重复的addEdge调用是更优雅的解决方案-或者出于某种原因更好。这些都是编程的半艺术半工程方面!
下面我将添加更多关于buildGraph函数的分解,以及如何在for...of循环之间切换变量-以防有人需要更多的说明。
您可以将buildGraph看作三个块:
第2部分。(for...of循环)首先执行。此for...of循环遍历整个“边”数组-在每次迭代中处理一个数组元素。每个edges元素都是一个字符串,格式为:"location_A - location_B“(对于真实示例:"Marketplace-Post Office")。
for...of循环使用解构来设置declare并将"from“和" to”赋值给“variables”,其中"from“被赋值(作为值):"location_A”和"to“被赋值为"location_B”。然后for...of循环使用"from“和"to”作为参数调用addEdge。
您可能会发现令人困惑的是,在for...of循环语句中调用addEdge时用作参数的"from“和"to”并不总是addEdge中相应的"from“和"to”。这是因为当for...of循环调用addEdge两次时,它会在两次调用addEdge之间切换"from“和" to”的顺序-首先调用addEdge(from,to),然后调用addEdge(to,from)。
现在,尽管for...of循环在调用addEdge时会切换这两个变量,但addEdge本身始终调用其第一个参数"from“和第二个参数"to”。
这意味着在第一个调用: addEdge( from,to)中,for...of循环中的"from“和"to”与addEdge函数中使用的"from“和"to”相同,但在第二个调用中: addEdge(to,from) -因为参数是切换的,所以在addEdge函数中使用的"from“的值(字符串)实际上是for...of循环的"to”的字符串值。
https://stackoverflow.com/questions/68192414
复制相似问题