为什么我让 NaN 使用此阵列

Why do I get NaN in working with this array?

本文关键字:阵列 NaN 为什么      更新时间:2023-09-26

我正在尝试用《雄辩的Javascript》一书来改进我的JS。 我正在研究问题 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));

最后两个控制台.log状态返回 NaN。

祖先是一个格式如下的数组:

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

我相信你对ageDifferences的定义缺乏对byName的参考。(以及防止byName[person.mother]未设置的安全措施。

问题就在这里,

return person.born - [person.mother].born

person.born是一个数字和[person.mother] 应该是数组(因为 [])(根据您的定义)。和[person.mother].born也应该是一个数字(根据要求)。所以,你不能使用[person.mother].born,你应该在你的对象中找到"person.mother"键的值。

当你这样做时,

console.log(average(ageDifferences));

方法"average"用于将数字数组作为参数。

由于年龄差异没有数字作为元素,因此它给出了 NaN 错误。

工作演示

NaN的原因是你试图减去 person.born - person.mother.born,第二个操作数甚至没有退出。所以它是数字 - 未定义。所以你得到了 NaN。

对于已知的母亲,您将其等同于null,这可能不符合所有条件。此外,您还需要更新knownMothers过滤器。您需要检查此人是否有母亲,以及母亲姓名是否也存在于 byName 对象中。如下所示:

var knownMothers = ancestry.filter(function(person){
          return person.mother && byName[person.mother];
        });

一旦你这样做了,你将能够得到年龄差异和平均值。

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