当我遇到这段关于总结祖先的代码时,正在浏览 Eloquent javascript 这本书。有几 block 板已经讨论了这个的不同部分,但我遇到麻烦的部分是这个 block :
var thisOneCounts = current != person && test ( current );
具体来说,什么时候 current 不是 == to person?我似乎找不到情况,因为当前总是被称为人。但显然我遗漏了一些东西,因为当我取出那段代码时,它会返回一个不同的解决方案。下面是完整的代码。
function reduceAncestors(person, f, defaultVal) {
function valueFor(person) {
if (person == null)
return defaultVal;
else
return f(person, valueFor(byName[person.mother]), valueFor(byName[person.father]));
}
return valueFor(person);
}
function countAncestors(person, test) {
function combine(current, fromMother, fromFather) {
var thisOneCounts = current != person && test(current); // **
return fromMother + fromFather + (thisOneCounts ? 1 : 0);
}
return reduceAncestors(person, combine, 0);
}
function longLivingPercentage(person) {
var all = countAncestors(person, function (person) {
return true;
});
var longLiving = countAncestors(person, function (person) {
return (person.died - person.born) >= 70;
});
return longLiving / all;
}
console.log(longLivingPercentage(byName["Emile Haverbeke"]));
最佳答案
请注意,reduceAncestors()
中的 valueFor()
函数是对原始人的 parent 递归调用的,然后是祖 parent 等。这些递归调用可能会使调用 f()
,而 f()
是来自 countAncestors()
的 combine()
函数。
因此,起始人物首先被传递给reduceAncestors()
。这会调用 f()
(即 combine()
内部函数),并使用父级调用 valueFor()
的结果。反过来,这将导致 mother 被传递给 f()
而 father 被传递给 f()
。回到最初调用 countAncestors()
的上下文中,person
仍然是 original person,但是 的传入值>current
到 combine()
会有所不同(它将是母亲或父亲或外祖母/祖父或祖母/祖父等)。
让我们看看 longLivingPercentage()
函数中对 countAncestors()
的第一次调用。我们传入起始人物和始终返回 true
的虚拟 test()
。我不知道代码期望家谱数据结构是什么,但我们假设它是这样的:
{
person: "Bob",
mother: {
person: "Mary",
mother: null,
father: null
},
father: {
person: "Jim",
mother: null,
father: null
}
}
因此:
- 为 Bob 调用了
countAncestors()
函数。 - 将 Bob 传递给
reduceAncestors()
,以及对该combine()
函数的引用。 - 在
reduceAncestors()
中,为 Bob 调用了valueFor()
,由于 Bob 不为空,我们调用了f()
— 即combine()
— 需要传递 Bob、母亲和父亲。 - 但是,在调用
f()
之前,我们需要用母亲和父亲调用valueFor()
,因为结果这些调用中的一部分需要传递给f()
。 - 所以
valueFor()
是和妈妈一起调用的。 也想调用f()
,它也需要检查母亲和父亲(即 Bob 的母亲的母亲和 Bob 的母亲)母亲的父亲)。 - 这两个祖 parent 调用很快就会失败,因为它们为空,因此可以继续为 Bob 的母亲调用
f()
。 - 现在我们在
combine()
中,第一个参数 —current
— 是 Bob 的母亲。combine()
函数实例的上下文来自person
是 Bob 时进行的函数调用,而 Bob 绝对不是他自己的母亲。
关于javascript - Eloquent Javascript Book 第 5 章关于递归和祖先的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37471924/