我正在尝试使用Book Eloquent Javascript来改进我的JS。我正在研究question 5.2的解决方案,并希望对它为什么出错以及返回NaN进行一些探索。我的解决方案是:
function average(array) {
function plus(a, b) { return a + b; }
return array.reduce(plus) / array.length;
}
var byName = {};
ancestry.forEach(function(person) {
byName[person.name] = person;
});
var knownMothers = ancestry.filter(function(person){
return person.mother != null;
});
var ageDifferences = knownMothers.map(function(person){
return person.born - [person.mother].born
});
console.log(knownMothers);
console.log(ageDifferences);
console.log(average(ageDifferences));
最后两个console.log statemets返回NaN。
ancestry是一个格式如下的数组:
[0: {
name: "Carolus Haverbeke"
sex: "m"
born: 1832
died: 1905
father: "Carel Haverbeke"
mother: "Maria van Brussel"
}
1: {
name: "Emma de Milliano"
sex: "f"
born: 1876
died: 1956
father: "Petrus de Milliano"
mother: "Sophia van Damme"
}]
解决方法是将此练习位于上面的链接中。它在代码中使用了byName对象,因此绕过了在输出中获取NaN。有人可以澄清为什么我需要在byName对象中返回元素吗?我知道它缺失的部分,但不知道为什么,真的想要理解。谢谢!
我复制了下面的答案(我不太了解)以供参考:
var differences = ancestry.filter(function(person) {
return byName[person.mother] != null;
}).map(function(person) {
return person.born - byName[person.mother].born;
});
console.log(average(differences));
答案 0 :(得分:0)
我认为您对ageDifferences
的定义缺少对byName
的引用。 (以及防范byName[person.mother]
未设置的安全措施。)
答案 1 :(得分:0)
问题出在这里,
return person.born - [person.mother].born
person.born是一个数字& [person.mother]应该是数组(因为[])(根据你的定义)。和[person.mother] .born也应该是一个数字(根据要求)。所以,你不能使用[person.mother] .born,你应该找到#34; person.mother"键入你的对象。
当你这样做时,
console.log(average(ageDifferences));
方法'平均'用于将数组作为参数。
因为,ageDifferences没有数字作为元素,它给出了NaN错误。
答案 2 :(得分:0)
NaN
的原因是你试图减去person.born - person.mother.born,其中第二个操作数甚至没有退出。所以它的数字 - 未定义。所以你得到了NaN。
对于knownMothers,你将它等同于null,这可能与所有条件都不匹配。您还需要更新knownMothers
过滤器。你需要检查这个人是否有一个母亲以及母姓是否存在于byName对象中。如下所示:
var knownMothers = ancestry.filter(function(person){
return person.mother && byName[person.mother];
});
一旦你这样做,你就能获得ageDifference和平均值。
var ancestry = [{
name: "Carolus Haverbeke",
sex: "m",
born: 1832,
died: 1905,
father: "Carel Haverbeke",
mother: "Maria van Brussel"
}, {
name: "Emma de Milliano",
sex: "f",
born: 1876,
died: 1956,
father: "Petrus de Milliano"
}, {
name : "Maria van Brussel",
sex: "m",
born: 1782,
died: 1905,
father: "Carel Haverbeke",
mother: "Maria van"
}];
function average(array) {
function plus(a, b) { return a + b; }
return array.reduce(plus) / array.length;
}
var byName = {};
ancestry.forEach(function(person) {
byName[person.name] = person;
});
var knownMothers = ancestry.filter(function(person){
return person.mother && byName[person.mother];
});
var ageDifferences = knownMothers.map(function(person){
return person.born - byName[person.mother].born;
// assumption: you are trying to get mother's born year from the byName object
});
console.log(knownMothers);
console.log(ageDifferences);
console.log(average(ageDifferences));