0

I have a multiplayer game and the gameplay data is stored like this:

var gameplays = [
    {id: "1", player1: "bob", player2: "tim", score1: 2, score2: 14},
    {id: "2", player1: "bob", player2: "tim", score1: 7, score2: 3},
    {id: "3", player1: "bob", player2: "tim", score1: 6, score2: 10},
    {id: "4", player1: "bob", player2: "tim", score1: 5, score2: 1}
];

What is the most efficient way to find the top 5 highscores from all the games by searching "score1" and "score2" and output them like this:

HIGHSCORES
1. Tim - 14
2. Tim - 10
3. Bob - 7
4. Bob - 6
5. Bob - 5

4 Answers 4

3
var scores = [];
for (var i = 0; i < gameplays.length; i++) {
    scores.push({score: gameplays[i].score1, name: gameplays[i].player1});
    scores.push({score: gameplays[i].score2, name: gameplays[i].player2});
}

scores.sort(function (a, b) {
    return b.score - a.score;
});

scores.splice(0, 5);

First, get the scores and flatten them in a scores array along with score and name of individual.

Then, we sort the array and splicing will get the top 5 scores with name.

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

3 Comments

.sort uses merge sort internally, so that will be the efficiency of this solution in terms of time complexity.
Do you think there is a way to get top 5 elements for both score1 and score2 separately and then flatten them together and do a second sort on just ten elements.
this also WORKS PERFECTLY! I am going to compare this to the other answer to see which is faster. thank u!!!!!!!!!!!!!!!!!!!!!!
1
const gameplays = [
    {id: "1", player1: "bob", player2: "tim", score1: 2, score2: 14},
    {id: "2", player1: "bob", player2: "tim", score1: 7, score2: 3},
    {id: "3", player1: "bob", player2: "tim", score1: 6, score2: 10},
    {id: "4", player1: "bob", player2: "tim", score1: 5, score2: 1}
];

First, write all relevant game information into an array of objects, each of which contain a player key corresponding to the player's name and a score key, which corresponds to the score:

const results = [];

gameplays.forEach(game => {
  for(let i = 1; i <= 2; i++) {
    results.push({});
    results[results.length - 1].player = `${game[`player${i}`].slice(0, 1).toUpperCase()}${game[`player${i}`].slice(1).toLowerCase()}`;
    results[results.length - 1].score = game[`score${i}`];
  }
});

Then, sort the array in descending order of scores before only keeping the top 5 with slice.

const topFive = results.sort((result1, result2) => result2.score - result1.score)
                       .slice(0, 5);

Finally, display the top 5 scores.

console.log('High Scores');

for(let i = 0; i < topFive.length; i++) {
  console.log(`${i + 1}. ${topFive[i].player} - ${topFive[i].score}`);
}

1 Comment

WORKS PERFECTLY! I am going to compare this to the answer by gauravmuk and see which one is faster. Thank you!!!
0

You can do it in a sort pretty easily I think with:

gameplays.sort(function(_a, _b){
    var a = _a.score1 > _a.score2 ? _a.score1 : _a.score2;
    var b = _b.score1 > _b.score2 ? _b.score1 : _b.score2;

    if(a < b) {
      return 1;
    }

    if(a > b) {
      return -1;
    }

    return 0;
})

Then, you you can access the top five with:

gameplays.slice(0, 5)

Comments

0

If you'r going to benchmark this I would be interested in the performance of the "functional" kind of solution with Ramda.

var gameplays = [
    {id: "1", player1: "bob", player2: "tim", score1: 2, score2: 14},
    {id: "2", player1: "bob", player2: "tim", score1: 7, score2: 3},
    {id: "3", player1: "bob", player2: "tim", score1: 6, score2: 10},
    {id: "4", player1: "bob", player2: "tim", score1: 5, score2: 1}
];

// find the 5 top highscores regardless which player
const normalizeScore = ({id, player1, score1, player2, score2}) => 
    [{id, player1, score: score1}, {id, player2, score: score2}];
const sortByScore = (play1, play2) => play2.score - play1.score;

const normalizeGameplays = R.chain(normalizeScore); // chain === flatMap
const sortGameplays = R.sort(sortByScore);
const topFive = R.slice(0, 5);

const highscore = R.compose(topFive, sortGameplays, normalizeGameplays);

console.log(highscore(gameplays));

@See: https://jsbin.com/wixowu/edit?html,js,console

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.