最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get the oldest person in this array - Stack Overflow

programmeradmin4浏览0评论

I'm practicing my javascript and I've e across the following array.

const people = [
  {
    name: 'Carly',
    yearOfBirth: 2018,
  },
  {
    name: 'Ray',
    yearOfBirth: 1962,
    yearOfDeath: 2011
  },
  {
    name: 'Jane',
    yearOfBirth: 1912,
    yearOfDeath: 1941
  },
]

i'm trying to find the oldest person in the array but I keep getting the wrong person.here's my code

  let findTheOldest = function(people) {
    const oldest = people.sort((a,b) => (a.yearOfDeath - a.yearOfBirth) > (b.yearOfDeath - b.yearOfBirth) ? -1 : 1);
    return oldest[0];
   }

so it keeps saying that 'Carly' is the oldest person rather than 'Ray'? How would I go about it? note that 'Carly' has no yearOfDeath and therefore she is still alive.

I'm practicing my javascript and I've e across the following array.

const people = [
  {
    name: 'Carly',
    yearOfBirth: 2018,
  },
  {
    name: 'Ray',
    yearOfBirth: 1962,
    yearOfDeath: 2011
  },
  {
    name: 'Jane',
    yearOfBirth: 1912,
    yearOfDeath: 1941
  },
]

i'm trying to find the oldest person in the array but I keep getting the wrong person.here's my code

  let findTheOldest = function(people) {
    const oldest = people.sort((a,b) => (a.yearOfDeath - a.yearOfBirth) > (b.yearOfDeath - b.yearOfBirth) ? -1 : 1);
    return oldest[0];
   }

so it keeps saying that 'Carly' is the oldest person rather than 'Ray'? How would I go about it? note that 'Carly' has no yearOfDeath and therefore she is still alive.

Share Improve this question edited Jul 8, 2020 at 0:17 Samuel Okoth asked Jul 7, 2020 at 23:54 Samuel OkothSamuel Okoth 1391 silver badge6 bronze badges 5
  • 3 When there's no year of death recorded you probably need to substitute the current year into that field before doing your calculation – ADyson Commented Jul 7, 2020 at 23:57
  • 1 when finding the oldest when there is no year of death you should use the current year in the calculation – Paul Baxter Commented Jul 7, 2020 at 23:58
  • Since they are still alive – GetSet Commented Jul 8, 2020 at 0:23
  • Have a look at the solution I presented. – Ahmed I. Elsayed Commented Jul 8, 2020 at 1:12
  • I would be tempted to question the logic of the task... I mean, do dead people even have an age? Then again, Google often tells us it's a dead persons 100th+ birthday, so maybe even death cannot stop you ageing? Meh, just a thought. – musefan Commented Jul 8, 2020 at 10:06
Add a ment  | 

3 Answers 3

Reset to default 12

You can use reduce, and use the current year for people without a death date:

const people = [{name:"Carly",yearOfBirth:2018},{name:"Ray",yearOfBirth:1962,yearOfDeath:2011},{name:"Jane",yearOfBirth:1912,yearOfDeath:1941}];

const findTheOldest = function(people) {
  const thisYear = new Date().getFullYear();

  return people.reduce((res, person) => {
    const age = (person.yearOfDeath || thisYear) - person.yearOfBirth;
    return age > res.age ? { person, age } : res;
  }, { person: null, age: 0 }).person;
}

console.log(findTheOldest(people)); // Ray

As an Engineer, most proofs I study at college assume something and we work it out, then at the end of the proof, Maths will tell you if your assumption was right.

We'll assume we have a function called getAge(person) that has a signature as follows.

// this performance improvement of storing the year was suggested by @blex
let currentYear = new Date().getFullYear();
let getAge = (person) => {
    return (person.yearOfDeath ? person.yearOfDeath : currentYear) - person.yearOfBirth
};

Basically, if the person doesn't have a .yearOfDeath, he's still alive and the current year 2020 at the time of writing this answer.

and we have a getOldest(people) that has a signature as follows.

let getOldest = people => {
    /** Keep in mind that people can be mutated and you 
        need to avoid this here
    */

    // An assumption. It can be right or wrong.
    let oldest_person = people[0];

    // The first method (slice) returns a shallow copy
    // the second one (splice) removes the oldest_person
    // removing it makes the loop count decrease by one. Nothing else.
    // we don't need a deep copy, we won't alter the people.
    people = (people.slice()).splice(1);

    // You could save the getAge(oldest_person) in a variable
    // instead of puting it each time
    // I wanted this to be as readable as possible.
    for (let person of people){
        if (getAge(person) > getAge(oldest_person)){
            // Congrats! we have a new older person!
            oldest_person = person;
        }
    }

    return oldest_person;

};

This has a worst-case time plexity of o(n).

For illustration, let's benchmark this.

let people = []
let init = () => {

    let randomInteger = (min, max) => { 
      // return random integer between min, max, found this on stackoverflow
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    for (let i = 0; i < 10000000; i++){ // 10m person
        let dateOfBirth = parseInt('19' + randomInteger(10,99));
        let dateOfDeath = parseInt('20' + randomInteger(10, 99));

        let person = {
            name: `person_${i}`,
            dateOfBirth, // same as dateOfBirth: dateOfBirth,
            dateOfDeath, // same logic
        }

        people.push(person); // add it to people

    }
}

init();

start = performance.now(); // time in millisecs
getOldest(people);
end = performance.now();  // time in millisecs after getting the oldest person

console.log((end - start ) * Math.pow(10, -3)) // time elapsed is around 0.2 secs.

To use sort to find the oldest, you need to include a default specifying the current year for people without a yearOfDeath. Below I've done this in a helper function called "age".

Using sort if your only purpose is to find a maximum can be inefficient though, particularly if you're dealing with a lot of data: try using reduce, as per other answer.

const people = [
  {
    name: "Carly",
    yearOfBirth: 2018,
  },
  {
    name: "Ray",
    yearOfBirth: 1962,
    yearOfDeath: 2011,
  },
  {
    name: "Jane",
    yearOfBirth: 1912,
    yearOfDeath: 1941,
  },
];

let findTheOldest = function (people) {
  const age = (x) => (x.yearOfDeath || new Date().getFullYear()) - x.yearOfBirth;
  const oldest = people.sort((a, b) =>
    age(a) > age(b) ? -1 : 1
  );
  return oldest[0];
};

console.log(findTheOldest(people));

发布评论

评论列表(0)

  1. 暂无评论