0

I have this array of Objects

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

and I am trying to get the oldest person , I have tried to use reduce method like this

const totalyears = people.reduce(
    (accumulator, age) => accumulator + age.yearOfDeath - age.yearOfBirth,
    0
);

console.log(totalyears);

but what I get instead of individual values for each name I get back the result of the total yearofDeadth minus the total yearOfBirth , that is 106; but what I am looking for is to get back something like his "Ray is the oldest person he is 49 years old"

I also tried to apply this other code but I get back the year as the object like this

let peopleobject = people.reduce(function (accumulator, person) {
    return { ...accumulator, [person.yearOfBirth]: person };
}, {});

console.log(peopleobject);

So how can I apply to the array of Objects reduce to get back what I am looking for? Please help, and thanks in advance.

11
  • 1
    How does "totalYears" mean "get oldest person"? Commented Jul 15, 2020 at 17:01
  • To see if one person is older than another you need to compare their ages. In JavaScript we use < and > to do these comparisons. How can you modify your code to do this? Commented Jul 15, 2020 at 17:04
  • 1
    @Cosmel Why are you so keen on using Array#reduce? Unless it's academic, a simple for loop with a variable to keep track of max age found so far should do the job. Commented Jul 15, 2020 at 17:07
  • 1
    @maazadeeb That was my first instinct, too. This problem certainly has an academic tinge to it, but if you think about it a while, the solution using reduce is much more elegant than a manual for loop. Commented Jul 15, 2020 at 17:09
  • 1
    @maazadeeb , yes basically is for academic purposes I need to learn how to apply reduce to the Array of Objects. Commented Jul 15, 2020 at 17:10

2 Answers 2

1

Let's build up a solution one step at a time. First we want to get the oldest person:

var oldestPerson = people.reduce(/* something goes here */);

This means that people.readuce() must return an object. So our call back that we pass in must also return an object:

var oldestPerson = people.reduce((accumulator, next) => {
    /* return a person object here */
});

But this also means that accumulator is also an object with a name, birth year, and death year. In otherwords accumulator is a person. And so is next.

Now to find the oldest of these two people, we need to calcualte their ages:

var oldestPerson = people.reduce((accumulator, next) => {
    var age1 = accumulator.yearOfDeath - accumulator.yearOfBirth;
    var age2 = next.yearOfDeath - next.yearOfBirth;

    /* do something */
});

Finally, we need to compare the ages of the two people to see who is older:

var oldestPerson = people.reduce((accumulator, next) => {
    var age1 = accumulator.yearOfDeath - accumulator.yearOfBirth;
    var age2 = next.yearOfDeath - next.yearOfBirth;

    if (age1 > age2)
        return accumulator;
    else
        return next;
});

The key here is to realize that accumulator is the oldest person found so far. We compare two people's ages at a time and return the older of the two.

Notice how I am thinking about this a step at a time. I write the code for each piece as I think it through. Don't try to write the entire solution all at once. This is the path to pain and suffering and still no solution. Break the solution into smaller pieces. Think through each step that you need to accomplish and write the code for just that step. After you finish all the steps you will have a fully functioning solution.

Also notice how I'm not keeping everything to a single line of code. I use variables to store the results of intermediate calculations and an if statement to make a decision. After getting this solution, you can try to reduce it back to a single line with a ternary operator. This is a reasonable exercise to learn how the ternary operator works, but in general, I prefer the version I came up here because I can come back to it later and understand what is going on.

Sign up to request clarification or add additional context in comments.

2 Comments

Missing step: handle empty arrays somehow (instead of throwing an exception). Maybe have a null-named 0-aged person as the initial value for the accumulator.
Thank you very much for showing me the way to tackle this step by step, is really clear what you are doing on every step. I was trying to apply the whole solution in one go, but breaking it down into small pieces makes a lot more sense. Thank you very much.
0

You don't want to accumulate, you want to replace the value with the new max value. So for each item check if it's the highest you've seen so far, and if so return it, otherwise return your old highest.

people.reduce(
  (oldest, person) =>
    person.yearOfDeath - person.yearOfBirth > oldest
      ? person.yearOfDeath - person.yearOfBirth
      : oldest,
  0
);

EDIT: to still use reduce we can cheat a little

let oldestPerson;
people.reduce(
  (oldest, person) =>
    person.yearOfDeath - person.yearOfBirth > oldest
      ? (oldestPerson = person, person.yearOfDeath - person.yearOfBirth)
      : oldest,
  0
);

5 Comments

This will get the oldest person's age. What if you want that person's name?
You're right. Then if we want to keep using reduce, we can cheat a little by using scoping differently. I'll edit my answer
If you want all the person's data, you have to rethink what you return from the reduce() callback.
Great solution and thank you very much for taking the time to help me and explain.
Btw, I wouldn't write code like this if others will also need to maintain it. I would write an explicit for loop, which would be most readable. Other possible solutions would be calculating and adding an age property to each object in the array if it'll be used more than once or if the array will be modified

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.