Issue 1 - User, Restaurants and Score

July 26, 2016

Question

You have an array of objects. Each object contains user, restaurant and score.

Return an array of objects that aggregates the unique pair of user and restaurant records and sum up their total score. See below for example.

Data


// The array you received is stored in "arr" variable
var arr = [
{ 'user': 1, 'restaurant': 2, 'score': 5 },
{ 'user': 2, 'restaurant': 3, 'score': 5 },
{ 'user': 1, 'restaurant': 2, 'score': 2 },
{ 'user': 1, 'restaurant': 2, 'score': 5 },
{ 'user': 2, 'restaurant': 3, 'score': 10 },
{ 'user': 2, 'restaurant': 3, 'score': 10 }
];

Expected Aggregated Data


// Answer should be returned in the following format.
[
{ 'user': 1, 'restaurant': 2, 'totalScore': 12 },
{ 'user': 2, 'restaurant': 3, 'totalScore': 25 }
]

Things to note


How To Submit Your Solution

Preferred Method

Solve the question in JSFiddle, JSBin or Codepen and save the link. Submit the link via email or paste it in the comment section below.

Alternative

Submit a gist.

Cut-off date

We will stop evaluating submission after 1st August, 2016 23:59. The answers will then be consolidated and the best few solutions will be picked. The selected solutions will be updated on this post.


My Answer

The snippet below is my answer. Needless to say, there is more than one way to solve a problem. So feel free to answer it with your own approach. You can use any ES version.

Click to reveal my answer


// Fork this bin before starting on this question
const arr = [
    { 'user': 1, 'restaurant': 2, 'score': 5 },
    { 'user': 2, 'restaurant': 3, 'score': 5 },
    { 'user': 1, 'restaurant': 2, 'score': 2 },
    { 'user': 1, 'restaurant': 2, 'score': 5 },
    { 'user': 2, 'restaurant': 3, 'score': 10 },
    { 'user': 2, 'restaurant': 3, 'score': 10 }
];

// Step 1: Reduce into a hashmap of "user,restaurant" keys
const reducedObj = arr.reduce((hash, obj) => {
  hash[`${obj.user},${obj.restaurant}`] = hash[`${obj.user},${obj.restaurant}`] || 0;
  hash[`${obj.user},${obj.restaurant}`] += obj.score;
  return hash;
}, {});

// Step 2: Transform into expected array format
const expectedAnswer = Object.keys(reducedObj).map((key) => {
  const splitKeys = key.split(',');
  return { user: +splitKeys[0], restaurant: +splitKeys[1], totalScore: reducedObj[key] }
});

console.log('Expected Answer', expectedAnswer);

JSBIN link here: Demo

Submissions

Picked a total of 5 submissions that display variations of solution. Thanks for participating. I personally picked up a few things and I hope you did too.

  1. Magic of ES6 by Youmoo
    This is my favourite submission. First, we see the code terseness that ES6 brings us. I also learnt something new: Object.values. I definitely will be using that more often.

    I made an update to my solution with Youmoo's method with a tiny improvement. See if you can spot it.

  2. Once is enough by banzomaikaka
    Another way to solve it in O(n) complexity. Code is concise and easy to read.

  3. O(n2) solutions

    • Solution by AaronLeoCooper
      Interesting. Uses only one data structure to solve the question
    • Solution by Craig Bilner
      Intense amount of testing data. Also included example of performance testing. Learnt about performance.now.
RSS

Like solving mini javascript questions? Subscribe below for more!

Subscribe to my newsletter on Modern Web Development

Weekly delivery of web goodies - Code Tips, 5CWS and Blog Updates