0

As I'm trying to get an object with all the names with the highest values, I am only getting one value and name rather than all existing names with the same highest value? // { name: 'Stephen', total: 85 }  Any help would be appreciated.

const students = [
{ name: 'Andy', total: 40 },
{ name: 'Seric', total: 50 },
{ name: 'Stephen', total: 85 },
{ name: 'David', total: 30 },
{ name: 'Phil', total: 40 },
{ name: 'Eric', total: 85 },
{ name: 'Cameron', total: 30 },
{ name: 'Geoff', total: 30 }];

const max = Math.max(...students.map(e => e.total))

const result = students.find(student => student.total === max)

console.log(result)//{ name: 'Stephen', total: 85 } 
1
  • If performance does matter for your use case, you might want to check out my answer below as it avoids looping twice over source array (to evaluate maximum total and to find out owners of max total). If that suits better to the purpose, upvote/accept are greatly welcome ;) Commented Dec 18, 2019 at 15:54

4 Answers 4

3

Use

const result = students.filter(student => student.total == max)
Sign up to request clarification or add additional context in comments.

1 Comment

Even though that one delivers expected output, there's a faster way, avoiding unnecessary looping to evaluate max
1

Another solution using a single forEach loop, which returns an array of the top students.

const students = [{ name: 'Andy', total: 40 },{ name: 'Seric', total: 50 },{ name: 'Stephen', total: 85 },{ name: 'David', total: 30 },{ name: 'Phil', total: 40 },{ name: 'Eric', total: 85 },{ name: 'Cameron', total: 30 },{ name: 'Geoff', total: 30 }];

const findTop = (students) => {
  let max = 0;
  let top = [];

  students.forEach(student => {
    if (student.total > max) {
      max = student.total;
      top = [student];
    } else if (student.total === max) {
      top.push(student);
    }
  })
  
  return top;
};

console.log(findTop(students));

5 Comments

No offence, but this one looks to me like a slightly more verbose and a bit suboptimal (due to re-creating resulting array upon each cycle) copy of my answer.
I had thought about wrapping it in function for some additional optimizations, I'll do that.
Now it has perfect readability on the upside and broken logic in case of negative total (which doesn't seem to be the case, though) on the downside, of course, if you don't want to use ugly -Infinity for the sake of algorithm robustness.
I assumed a student couldn't have a negative grade, which is usually the case. That value could be tweaked if using some odd grading system.
However, now it's clean and readable, thus deserves an upvote from my end.
0

One pass over the array is absolutely enough to do the job with Array.prototype.reduce():

const students=[{name:'Andy',total:40},{name:'Seric',total:50},{name:'Stephen',total:85},{name:'David',total:30},{name:'Phil',total:40},{name:'Eric',total:85},{name:'Cameron',total:30},{name:'Geoff',total:30}],
      result = students.reduce((res,student,idx) => (
        !idx || student.total > res[0]['total'] ?
        res = [student] :
        student.total == res[0]['total'] ?
        res.push(student) :
        true
      , res),[])
        
console.log(result)
.as-console-wrapper {min-height:100%}

Comments

0

You could take a single loop with reduce by returning the object with the greatest total.

const
    students = [{ name: 'Andy', total: 40 }, { name: 'Seric', total: 50 }, { name: 'Stephen', total: 85 }, { name: 'David', total: 30 }, { name: 'Phil', total: 40 }, { name: 'Eric', total: 85 }, { name: 'Cameron', total: 30 }, { name: 'Geoff', total: 30 }]
    highest = students.reduce((r, o) => {
        if (!r || r[0].total < o.total) return [o];
        if (r[0].total === o.total) r.push(o);
        return r;
    }, undefined);

console.log(highest);

4 Comments

OP's problem was to find out all owners of the max 'total', finding single winner is what he already achieved (in more efficient manner, by the way, using find()). You're right, though, reduce() is a very powerful thing, so it may solve the problem even better than OP does expect.
right. but op need two iterations instead of an optimized one.
@NinaScholz : check out my solution in that regard
@YevgenGorbunkov, sorry didn't read the question in depth ... ;-)

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.