0

I'm trying to calculate the total point scored per player per question.

For each question, I'm retrieving the data in the following format.

[
  {
    "_id":"5ab24e5e49e0f20a06d73ab7",
    "player":"Kareltje",
    "answers":
    [
      {
        "_id":"5ab227cf07818240934b11a5",
        "player":"Peter",
        "comment":"",
        "points":7,
        "__v":0
      },
      {
        "_id":"5ab24bf3b8494c76fd0bb31a",
        "player":"André",
        "comment":"",
        "points":6,
        "__v":0
      },
      {
        "_id":"5ab24bf7b8494c76fd0bb31b",
        "player":"Maikel",
        "comment":"",
        "points":5,
        "__v":0
      },
      {
        "_id":"5ab24bfab8494c76fd0bb31c",
        "player":"Iebele",
        "comment":"",
        "points":4,
        "__v":0
      },
      {
        "_id":"5ab24bfeb8494c76fd0bb31d",
        "player":"Bettina",
        "comment":"",
        "points":3,
        "__v":0
      },
      {
        "_id":"5ab24c01b8494c76fd0bb31e",
        "player":"Shirley",
        "comment":"",
        "points":2,
        "__v":0
      },
      {
        "_id":"5ab24c04b8494c76fd0bb31f",
        "player":"Suzanne",
        "comment":"",
        "points":1,
        "__v":0
      }
    ],
    "question":1,"__v":0
  },
  {
    "_id":"5ab24fa21e7caa1132720e7a",
    "player":"Maikel",
    "answers":
    [
      {
        "_id":"5ab24c04b8494c76fd0bb31f",
        "player":"Suzanne",
        "comment":"",
        "points":7,
        "__v":0
      },
      {
        "_id":"5ab24bfab8494c76fd0bb31c",
        "player":"Iebele",
        "comment":"",
        "points":6,
        "__v":0
      },
      {
        "_id":"5ab24bf3b8494c76fd0bb31a",
        "player":"André",
        "comment":"",
        "points":5,
        "__v":0
      },
      {
        "_id":"5ab24c01b8494c76fd0bb31e",
        "player":"Shirley",
        "comment":"",
        "points":4,
        "__v":0
      },
      {
        "_id":"5ab24bf7b8494c76fd0bb31b",
        "player":"Maikel",
        "comment":"",
        "points":3,
        "__v":0
      },
      {
        "_id":"5ab24bfeb8494c76fd0bb31d",
        "player":"Bettina",
        "comment":"",
        "points":2,
        "__v":0
      },
      {
        "_id":"5ab227cf07818240934b11a5",
        "player":"Peter",
        "comment":"",
        "points":1,
        "__v":0
      }
    ],
    "question":1,"__v":0
  }
]

I'm want to have a total score for each player based on this data, but I can't seem to find a code, to add up the points per player.

The result be something like: Peter: 14 André: 12 Maikel: 10 Iebele: 8

Any ideas on how to achieve this?

I've tried to get the points with the following code:

var { data, players } = this.state;
var ArrLength = data.length;
console.log(data);
var j;
var x;
for (j = 0; j < ArrLength; j++) {
  let answer = data[j].answers;
  for (x = 0; x < answer.length; x++) {
    console.log(answer[`${x}`].points);
  }
}

This at least show me the points per player in the console.log. But now adding them to get an end result is something I can't seem to figure out.

4 Answers 4

2

You could use a Map for counting and build an array with the data.

var data = [{ answers: [{ _id: "5ab227cf07818240934b11a5", player: "Peter", comment: "", points: 7, __v: 0 }, { _id: "5ab24bf3b8494c76fd0bb31a", player: "André", comment: "", points: 6, __v: 0 }, { _id: "5ab24bf7b8494c76fd0bb31b", player: "Maikel", comment: "", points: 5, __v: 0 }, { _id: "5ab24bfab8494c76fd0bb31c", player: "Iebele", comment: "", points: 4, __v: 0 }], player: "Pieter", question: 1, __v: 0, _id: "5ab24e5e49e0f20a06d73ab7" }, { answers: [{ _id: "5ab227cf07818240935b11a5", player: "Peter", comment: "", points: 7, __v: 0 }, { _id: "5ab24bf3b8494c76fd8bb31a", player: "André", comment: "", points: 6, __v: 0 }, { _id: "5ab24bf7b8494c76fd2bb31b", player: "Maikel", comment: "", points: 5, __v: 0 }, { _id: "5ab24bfab8494c76fd9bb31c", player: "Iebele", comment: "", points: 4, __v: 0 }], player: "Kareltje", question: 1, __v: 0, _id: "5ab24e5e49e0f20b86d73ab7" }],
    score = Array.from(
        data.reduce((m, { answers }) =>
            answers.reduce((n, { player, points }) =>
                n.set(player, (n.get(player) || 0) + points), m), new Map),
        ([player, score]) => ({ player, score })
    );

console.log(score);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

2 Comments

I would always try to use a map function instead of different for-loops (for each, for in etc.), so this is imo the solution OP should choose to work with.
I'm getting an data.reduce is not a function error when trying this code.
2

You can use this alternative.

Using the function reduce and the function forEach.

  • reduce to accumulate.
  • forEach to loop over the answers.

var data = [{    answers: [        {            _id: "5ab227cf07818240934b11a5",             player: "Peter",             comment: "",             points: 7,             __v: 0        }        , {            _id: "5ab24bf3b8494c76fd0bb31a",             player: "André",             comment: "",             points: 6,             __v: 0        }        , {            _id: "5ab24bf7b8494c76fd0bb31b",             player: "Maikel",             comment: "",             points: 5,             __v: 0        }        , {            _id: "5ab24bfab8494c76fd0bb31c",             player: "Iebele",             comment: "",             points: 4,             __v: 0        }    ],    player: "Pieter",    question: 1,    __v: 0,    _id: "5ab24e5e49e0f20a06d73ab7"},{    answers: [        {            _id: "5ab227cf07818240935b11a5",             player: "Peter",             comment: "",             points: 7,             __v: 0        },         {            _id: "5ab24bf3b8494c76fd8bb31a",             player: "André",             comment: "",             points: 6,             __v: 0        }        , {            _id: "5ab24bf7b8494c76fd2bb31b",             player: "Maikel",             comment: "",             points: 5,             __v: 0        }        ,{            _id: "5ab24bfab8494c76fd9bb31c",             player: "Iebele",             comment: "",             points: 4,             __v: 0        }    ],    player: "Kareltje",    question: 1,    __v: 0,    _id: "5ab24e5e49e0f20b86d73ab7"}];

var result = data.reduce((a, {answers}) => {
  answers.forEach(({player, points}) =>  a[player] = (a[player] || 0) + points);
  return a;
}, {});


console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

I'm getting an data.reduce is not a function error when trying this code.
1

You can use .reduce to iterate through the array and aggregate all the scores:

const data = [{"answers":[{"_id":"5ab227cf07818240934b11a5","player":"Peter","comment":"","points":7,"__v":0},{"_id":"5ab24bf3b8494c76fd0bb31a","player":"André","comment":"","points":6,"__v":0},{"_id":"5ab24bf7b8494c76fd0bb31b","player":"Maikel","comment":"","points":5,"__v":0},{"_id":"5ab24bfab8494c76fd0bb31c","player":"Iebele","comment":"","points":4,"__v":0}],"player":"Pieter","question":1,"__v":0,"_id":"5ab24e5e49e0f20a06d73ab7"},{"answers":[{"_id":"5ab227cf07818240935b11a5","player":"Peter","comment":"","points":7,"__v":0},{"_id":"5ab24bf3b8494c76fd8bb31a","player":"André","comment":"","points":6,"__v":0},{"_id":"5ab24bf7b8494c76fd2bb31b","player":"Maikel","comment":"","points":5,"__v":0},{"_id":"5ab24bfab8494c76fd9bb31c","player":"Iebele","comment":"","points":4,"__v":0}],"player":"Kareltje","question":1,"__v":0,"_id":"5ab24e5e49e0f20b86d73ab7"}];

const scores = data.reduce( (scores, d) => {
  
  d.answers.forEach( answer => {
    scores[answer.player] = (scores[answer.player]||0) + answer.points;
  });

  return scores;
}, {});

console.log(scores);

4 Comments

I'm getting an data.reduce is not a function error when trying this code.
@Maikey I had to alter the example data you posted to be correct JSON. You can see the data I used in the example.
I've editted the data in the post. That's the exact data I'm getting returned from mongodb. Still a data.reduce error. I've also checked it with the data you're using, but it seems the same to me...
Never mind... already figured it out. Made a stupid mistake in the initial state. Had it set to {} instead of []. This was the reason why it didn't work.
1

You can simply do it with an external array. It basically uses the same key for each element in points, it verifies if the key is set already (if not, sets as zero), and sums points related with same key.

PS: _id is not unique in your json.

Since the JSON you gave is not valid, I'm using the following one:

var arr = [
    {
        answers: [{
                _id: "5ab227cf07818240934b11a5", 
                player: "Peter", 
                comment: "", 
                points: 7, 
                __v: 0
            }, {
                _id: "5ab24bf3b8494c76fd0bb31a", 
                player: "André", 
                comment: "", 
                points: 6, 
                __v: 0
            }, {
                _id: "5ab24bf7b8494c76fd0bb31b", 
                player: "Maikel", 
                comment: "", 
                points: 5, 
                __v: 0
            }, {
                _id: "5ab24bfab8494c76fd0bb31c", 
                player: "Iebele", 
                comment: "", 
                points: 4, 
                __v: 0
            }
        ],
        player: "Pieter",
        question: 1,
        __v: 0,
        _id: "5ab24e5e49e0f20a06d73ab7"
    }, {
        answers: [{
                _id: "5ab227cf07818240935b11a5", 
                player: "Peter", 
                comment: "", 
                points: 7, 
                __v: 0
            }, {
                _id: "5ab24bf3b8494c76fd8bb31a", 
                player: "André", 
                comment: "", 
                points: 6, 
                __v: 0
            }, {
                _id: "5ab24bf7b8494c76fd2bb31b", 
                player: "Maikel", 
                comment: "", 
                points: 5, 
                __v: 0
            }, {
                _id: "5ab24bfab8494c76fd9bb31c", 
                player: "Iebele", 
                comment: "", 
                points: 4, 
                __v: 0
            }
        ],
        player: "Kareltje",
        question: 1,
        __v: 0,
        _id: "5ab24e5e49e0f20b86d73ab7"
    }
]

var points = {};
for (var i in arr) {
    for (var j in arr[i].answers) {
        if (!points[arr[i].answers[j].player]) {
            points[arr[i].answers[j].player] = 0;
        }
        points[arr[i].answers[j].player] += arr[i].answers[j].points;
    }
}

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.