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
- The values of
user
,restaurant
andscore
are dynamic - Remember to preserve data types
- Sorting is not needed
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.
// 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.
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.
Once is enough by banzomaikaka
Another way to solve it in O(n) complexity. Code is concise and easy to read.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 aboutperformance.now
.
- Solution by AaronLeoCooper
Like solving mini javascript questions? Subscribe below for more!