Skip to content

Instantly share code, notes, and snippets.

@Matt-T-Git
Last active June 3, 2020 14:33
Show Gist options
  • Save Matt-T-Git/0a37f918b02fbd1944e62c051aaa3001 to your computer and use it in GitHub Desktop.
Save Matt-T-Git/0a37f918b02fbd1944e62c051aaa3001 to your computer and use it in GitHub Desktop.
Technical exercise answer with comments -- Company House Challenge
/**
* Technical Exercise Answer, Companies House
* Mathew Thomas 16/05/2020
*/
const express = require('express'); // Express NodeJS module
const path = require('path'); // Path NodeJS module
const bodyParser = require('body-parser'); // Body-Parser NodeJS module
const port = 8080; // Define port as 8080 as per exercise requirements
const app = express(); // Create app object
app.use(bodyParser.json()); // app use bodyparser
/* This data would usually be stored in a database but,
for the sake of this exercise I will define as a const */ // No SQL database, MongoDB perhaps?
// Define games data
const games = [
{
"title": "Uncharted 4",
"id": 1,
"description": "For the first time ever in Uncharted history, drive vehicles during gameplay",
"by": "Sony",
"platform": ["PS4"],
"age_rating": "16",
"likes": 100,
"comments": [{
"user": "bob",
"message": "Cracking game far too much cinematic",
"dateCreated": "2011-01-03",
"like": 6
}, {
"user": "testingPriest",
"message": "Not enough shooting for me,far too easy ",
"dateCreated": "2011-04-02",
"like": 5
}]
},
{
"title": "Call of Duty, Infinite Warfare",
"id": 2,
"description": "Fast paced shooter",
"by": "Infiniward",
"platform": ["XBOX", "PS4"],
"age_rating": "18",
"likes": 40,
"comments": [{
"user": "jim",
"message": "Awesome game",
"dateCreated": "2015-01-25",
"like": 7
}, {
"user": "Dave",
"message": "Too many n00bs ",
"dateCreated": "2016-05-00",
"like": 8
}, {
"user": "bob",
"message": "some comment",
"dateCreated": "2011-09-19",
"like": 2
}, {
"user": "richard",
"message": "some other comment",
"dateCreated": "2011-10-19",
"like": 1
}]
}
]
//// Part 2 Task ////
// Get Games Report
app.get('/games/report', (req, res) => {
console.log('Returning games report');
/// Highest likes
var highestLikes = getMax(games, "likes"); // Get the game with highest number of likes -- (getMax function below) pass in array and key of json object to compare
/// Most comments
var comms = []; // Init comments array
var usrs = []; // Init users arry
var msgs = []; // Init messages array
// Loop through games array and extract comments array into its own array -- comms (minus the game info -- title etc...) -- just to make simpler cleaner data to work with
for (var i = 0; i < games.length; i++) {
comms.push(games[i].comments);
}
// Loop through comms array and extract each message object into its own array (msgs) we now have an array of only comnments - no info on which comment belongs to which game
for (var i = 0; i < comms.length; i++) {
if (comms.hasOwnProperty(i)) {
msgs.push(comms[i]);
}
}
// As we still have messages as an array of arrays we need to join the arrays to create a sinlge array then extract only the user key value and push to array containing only the users (usrs)
var mergedMessgaeArray = [].concat.apply([], msgs);
for (var i = 0; i < mergedMessgaeArray.length; i++) {
usrs.push(mergedMessgaeArray[i].user);
}
// Avg likes per game
var gameArr = []; // Init array to hold new game objects
// Loop over the games array
for (var i = 0; i < games.length; i++) {
// Loop each game in the games array
for (game of games) {
// Create a new game object (gme) to append to our game array (gameArr)
var gme = new Object();
gme.title = game.title; // Append game title to gme object
gme.comments = game.comments; // Append game comment to gme object
gme.commentCount = gme.comments.length; // Set gme object commentCount property to ammount of comments the object has
var commentTotalValue = 0;
// Loop through the gme object comments and appnend the likes value to a variable (commentTotalValue)
for (var c of gme.comments) {
commentTotalValue += c.like;
}
// Get the avg likes value by dividing the total comment count (commentTotalValue) by the gme object total number of comments (gme.commentCount) & round up to the nearest integer using Math.ceil
gme.averageLikeValue = Math.ceil(commentTotalValue / gme.commentCount);
// Create an object thatr contains the game title and avg likes & push to gameArr array
var obj = new Object();
obj.title = gme.title;
obj.average_likes = gme.averageLikeValue;
gameArr.push(obj);
}
}
// Return Object --> Create our return object (Gather all data relevant data into an obj)
var returnObject = new Object();
returnObject.user_with_most_comments = highest(usrs); // Set obj user with the most comments (using highest function below)
returnObject.highest_rated_game = highestLikes.title; // Set obj ighest rated game title
returnObject.average_likes_per_game = gameArr; // Set avg like per game array
res.send(returnObject); // Return the object
});
//// Part 1 Task ////
// Get game by ID
app.get('/games/**', (req, res) => {
console.log('Returning game by ID');
const gameId = parseInt(req.params[0]); // Get the game ID passed in the GET request
const foundGame = games.find(subject => subject.id === gameId); // Find the game in games where the game ID (subject.id) is equal to the game ID passed in the GET request
if (foundGame) { // If we find a game that matches the request the we assign the game attriubutes to the request attributes & return the foundgame object
for (let attribute in foundGame) {
if (req.body[attribute]) {
foundGame[attribute] = req.body[attribute];
console.log(`Set ${attribute} to ${req.body[attribute]} in game: ${gameId}`);
}
}
res.send(foundGame);
} else { // If no game was found for the supplied ID we return a 404 and log to console 'game not found'
console.log(`Game not found.`);
res.status(404).send();
}
});
//// Helpers ////
// Get Max (compare array elements and find max)
function getMax(arr, prop) { // Pass in the array and element to parse
var max;
for (var i = 0; i < arr.length; i++) { // Loop through the games array
if (max == null || parseInt(arr[i][prop]) > parseInt(max[prop])) // compare each element Int value
max = arr[i]; // max holds each pass of the loop max
}
return max; // return the max
}
// Highest appearences (Pass array to compare key values)
// Get greatest of an array of objects key values using reduce function & compare element values
const highest = arr => (arr || []).reduce((acc, el) => {
acc.k[el] = acc.k[el] ? acc.k[el] + 1 : 1
acc.max = acc.max ? acc.max < acc.k[el] ? el : acc.max : el
return acc
}, { k: {} }).max
// App listen on port 8080
console.log(`Games service listening on port ${port}`);
app.listen(port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment