27

I have a array called games with a value votes,

let games = [
    { id: 1, name: 'Star Wars: Imperial Assault', company: company.Fantasy_Flight, available: true, category: Category.SciFi, votes: 3},
    { id: 2, name: 'Game of Thrones: Second Edition', company: 'Fantassy Flight', available: false, category: Category.Fantasy, votes: 4 },
    { id: 3, name: 'Merchans and Marauders', company: 'Z-Man Gaming', available: true, category: Category.Pirates, votes: 5 },
    { id: 4, name: 'Eclipse', company: 'Lautapelit', available: false, category: Category.SciFi, votes: 6 },
    { id: 5, name: 'Fure of Dracula', company: 'Fantasy Flight', available: true, category: Category.Fantasy, votes: 2 }
]

I want to return the object with the most amount of votes. I've googled and found some methods using Math.max.apply, but it's returning the number of votes, and not the object itself.

function selectMostPopular():string {
    const allGames = getAllGames();
    let mostPopular: string = Math.max.apply(Math, allGames.map(function (o) { return o.votes; }));
    console.log(mostPopular);
    return mostPopular;
};

Any tips on how to return the object with the highest votes?

4 Answers 4

57

You can do a simple one-line reduce:

let maxGame = games.reduce((max, game) => max.votes > game.votes ? max : game);

Note: You should make sure games is not empty before you hit this code. As pointed out in the comments, this code will throw an error if games is empty.

(You could instead provide an initial value to .reduce to avoid the error. But it'll usually be most straightforward to check whether games is empty to begin with, rather than provide a dummy/default value and then later checking whether you got that dummy/default value.)

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

3 Comments

Thanks for the answer. It's working like intended. Quick question though. What is the max in this context?
max is always the game that has the most votes so far. If game has more votes than max, then it becomes max on the next iteration, and so on until the end of the array is reached.
This particular code will fail if games is empty because no default value is provided to .reduce.
10

You can use Array#map and Array#find

// First, get the max vote from the array of objects
var maxVotes = Math.max(...games.map(e => e.votes));

// Get the object having votes as max votes
var obj = games.find(game => game.votes === maxVotes);

(function () {
    var games = [{
        id: 1,
        name: 'Star Wars: Imperial Assault',
        company: 'company.Fantasy_Flight',
        available: true,
        category: 'Category.SciFi',
        votes: 3
    }, {
        id: 2,
        name: 'Game of Thrones: Second Edition',
        company: 'Fantassy Flight',
        available: false,
        category: 'Category.Fantasy',
        votes: 4
    }, {
        id: 3,
        name: 'Merchans and Marauders',
        company: 'Z-Man Gaming',
        available: true,
        category: 'Category.Pirates',
        votes: 5
    }, {
        id: 4,
        name: 'Eclipse',
        company: 'Lautapelit',
        available: false,
        category: 'Category.SciFi',
        votes: 6
    }, {
        id: 5,
        name: 'Fure of Dracula',
        company: 'Fantasy Flight',
        available: true,
        category: 'Category.Fantasy',
        votes: 2
    }];

    var maxVotes = Math.max(...games.map(e => e.votes));
    var obj = games.find(game => game.votes === maxVotes);
    console.log(obj);

    document.body.innerHTML = '<pre>' + JSON.stringify(obj, 0, 4);
}());

Comments

3

What about sorting based on number of votes?

games.sort( function(a, b){
    return a.votes < b.votes; 
}); 

Now the first game in the array has the most votes.

Comments

2

Just iterate, updating the maximum value and the object in which to find it when you find a greater value:

var max = -Infinity, argmax;
for(var game of games)
  if(game.votes >= max)
    max = game.votes, argmax = game;
argmax;

Comments

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.