繁体   English   中英

Javascript,使用reduce数组方法

[英]Javascript, using the reduce array method

所以我正在做奥丁项目。 其中一个练习现在暗示使用 reduce 方法。 我有点卡在这里,我已经看过解决方案了。 但是,如果我自己这样做,我真的不知道自己会犯什么样的错误。 我得到的代码是这样的:

let findTheOldest = function(people) {
    const oldestPerson = people.reduce((winner, person) => {
        if ((person.yearOfDeath - person.yearOfBirth) > (winner.yearOfDeath - winner.yearOfBirth)) {
            return person;
        } else if ((person.yearOfDeath - person.yearOfBirth) <= (winner.yearOfDeath - winner.yearOfBirth)) {
            return winner;
        }
    });
}

他们拥有的代码是:

const findTheOldest = function(array) {
  return array.reduce((oldest, currentPerson) => {
    const oldestAge = getAge(oldest.yearOfBirth, oldest.yearOfDeath)
    const currentAge = getAge(currentPerson.yearOfBirth, currentPerson.yearOfDeath)
    return oldestAge < currentAge ? currentPerson : oldest
  })
}

const getAge = function(birth, death) {
  if (!death) {
    death = new Date().getFullYear();
  }
  return death - birth;
}

现在,我知道,如果我看一下,他们的代码会更加结构化。 但我自己的“解决方案”是我最接近的一个。 到现在为止,我正试图弄清楚有什么区别。 我知道他们的代码最终会更好。 它更加整洁,并且使用单独的变量来存储年龄更加清晰和清晰。 然而,我和他们都以同样的方式返回“对象”。 对于我应该能够通过的第一个测试用例,这就是我现在的想法。

也许我必须解释测试用例,第一个是根据 yearBirth 和 yearDeath 计算年龄来找到最年长的人。 然后第二个测试用例应该解释一个还活着的人。 第三个测试用例是活着的人实际上是最年长的人,所以它应该返回那个人。 我现在只尝试第一个。

我得到的错误是“无法读取未定义的属性'名称'”。 我认为这与解决方案试图访问我要返回的 object 的 name 属性有关。 因为这是他们的提示:

  • 您应该返回整个人 object,但测试大多只是检查以确保名称正确。

有可能没有yearOfDeath (如果该人没有死)在这种情况下,您的代码将检索undefinedundefined - yearOfBirth会给您NaN

NaN的任何比较都是false的,因此您不会在if分支中使用 go ,在else if分支中也不会。 因此,您不会返回任何东西。 如果你用一个简单的else替换else if你会返回一些东西,但它可能是一个错误的结果,因为比较是错误的。

这就是为什么如果没有yearOfDeath ,他们制作了 function 来检索当前年份。

您还需要在 function 的末尾返回oldestPerson变量。

在您的代码中,您可以添加类似(person.yearOfDeath || currentYear)

 let findTheOldest = function(people) { const currentYear = new Date().getFullYear(); const oldestPerson = people.reduce((winner, person) => { if (((person.yearOfDeath || currentYear) - person.yearOfBirth) > ((winner.yearOfDeath || currentYear) - winner.yearOfBirth)) { return person; } else if (((person.yearOfDeath || currentYear) - person.yearOfBirth) <= ((winner.yearOfDeath || currentYear) - winner.yearOfBirth)) { return winner; } }); return oldestPerson; } const p1 = { yearOfBirth: 1990, yearOfDeath: 2015 } const p2 = { yearOfBirth: 1990 } // Edge case: calculate his age with current year console.log(findTheOldest([p1, p2]))

现在这段代码很难阅读,这就是为什么最好将它拆分成单独的函数。

我注意到的几件事——

  • 当我们不打算重新分配变量时使用const (而不是let
  • 使用初始值(第二个参数) reduce数据集为空时防止程序炸毁
  • reduce中使用复合结果可以防止我们在每次迭代中重新计算oldest的人的年龄
  • 使用默认值可防止 null 检查、不必要的变量重新分配,并避免遇到NaN 默认值还向程序员表明 function 接受什么类型的数据

 const findTheOldest = (people = []) => people.reduce ( ([ oldest, oldestAge ], person) => { const age = getAge(person) // only compute age of current person return age > oldestAge? [ person, age ]: [ oldest, oldestAge ] }, [ undefined, -Infinity ] // initial value ) [0] // reduce returns [ <person>, <age> ], [0] gets the person out const getAge = ({ yearOfBirth = 0, yearOfDeath = 0 }) => yearOfDeath? yearOfDeath - yearOfBirth: (new Date).getFullYear() - yearOfBirth const peeps = [ { name: "Alice", yearOfBirth: 2000 }, { name: "Gertrude", yearOfBirth: 1910 }, { name: "Martha", yearOfBirth: 1900, yearOfDeath: 2006 }, { name: "Wanda", yearOfBirth: 1940 } ] // works as expected console.log(findTheOldest(peeps)) // { name: "Gertrude", ... } // works when data source is empty console.log(findTheOldest([])) // undefined // works when data is missing. console.log(findTheOldest()) // undefined

试试这个:

 let findTheOldest = function(people) { const oldestPerson = people.reduce((winner, person) => { if ((person.yearOfDeath - person.yearOfBirth) > (winner.yearOfDeath - winner.yearOfBirth)) { return person; } else if ((person.yearOfDeath - person.yearOfBirth) <= (winner.yearOfDeath - winner.yearOfBirth)) { return winner; } }); return oldestPerson; }

是一样的,但是我只是在 function 的末尾添加了 return oldPerson。 告诉我它是否有效

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM