2

Problem:

I am working on a mini project involving a JSON file and express/nodejs and I am stuck on a portion that contains the following instructions:

Using a post route, determine the user's most compatible friend using the following rules: Convert each user's results into a simple array of numbers.

Compare the difference between current user's scores against those from potential matches, question by question. Add up the differences to calculate the totalDifference.

Example: User 1: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1] User 2: [3, 2, 6, 4, 5, 1, 2, 2, 4, 1]

Total Difference: 2 + 1 + 2 + 3 = 8

Remember to use the absolute value of the differences; no negative results! Your app should calculate both 5-3 and 3-5 as 2, etc.

I am able to get the results that look like this (the submitted array is the last array all 5's):

results

Here is the portion of code I am using for that:

app.post('/surveyResponse', function(req,res){
   let photo = req.body.url;
   let name = req.body.name;
   let travel = req.body.travel;
   let affection = req.body.affection;
   let family = req.body.family;
   let fitness = req.body.fitness;
   let movie = req.body.movie;
   let education = req.body.education;
   let career = req.body.career;
   let marriage = req.body.marriage;
   let children = req.body.children;
   let pets = req.body.pets;
   let sum = 0;
   let obj = {};
   let person = {
       name: name,
       photo: photo,
       scores: [
           travel,
           affection,
           family,
           fitness,
           movie,
           education,
           career,
           marriage,
           children,
           pets
       ]
   }
//finding the sum of all the numbers
for(i in person.scores){
   sum+=Number(person.scores[i]);
}
//form submission results
let score = person.scores;
// Read the file and send to the callback
fs.readFile('./app/data/friends.json', handleFile)
// Write the callback function
function handleFile(err, data) {
   if (err) throw err
   obj = JSON.parse(data)

   for(var key in obj){
       var obj2 = obj[key];
       console.log(obj2.scores);
   }
   //this is the console.log for my form submission array
   console.log(score);
}
//------------------------------------
// result that prints out on the HTML
res.send('Your name is ' + name + ' You Score is ' + sum );
});

GOAL

The goal is the find the user with the least difference between their results and what the user submitted.

RESEARCH

I have done research How to compare each object in an array with each other. When found update the object with a new property How to Subtract Multiple Objects from an Array with Another array and most of the examples deal with having separate JSON objects and comparing them to each other and the one I found that compared an array of JSON objects was just comparing phone numbers. I am stuck on my next steps. I just need a jump start/guidance please.

Here is the JSON file I am working with:

[
 {
   "name": "Mike Jackson",
   "photo": "./app/public/matchPhotos/photo0.jpg",
   "scores": [
     "3",
     "2",
     "4",
     "3",
     "3",
     "4",
     "4",
     "4",
     "3",
     "4"
   ]
 },
 {
   "name": "Jermaine Subia",
   "photo": "./app/public/matchPhotos/photo1.jpg",
   "scores": [
     "4",
     "4",
     "2",
     "2",
     "4",
     "5",
     "3",
     "4",
     "5",
     "2"
   ]
 },
 {
   "name": "Taji Gibson",
   "photo": "./app/public/matchPhotos/photo2.jpg",
   "scores": [
     "1",
     "5",
     "3",
     "2",
     "3",
     "1",
     "3",
     "4",
     "3",
     "3"
   ]
 },
 {
   "name": "Jamie Schully",
   "photo": "./app/public/matchPhotos/photo3.jpg",
   "scores": [
     "5",
     "3",
     "3",
     "4",
     "2",
     "4",
     "4",
     "5",
     "5",
     "5"
   ]
 },
 {
   "name": "Justin Andres",
   "photo": "./app/public/matchPhotos/photo4.jpg",
   "scores": [
     "2",
     "1",
     "1",
     "1",
     "2",
     "3",
     "2",
     "2",
     "2",
     "4"
   ]
 },
 {
   "name": "Austin Brooks",
   "photo": "./app/public/matchPhotos/photo5.jpg",
   "scores": [
     "2",
     "3",
     "4",
     "2",
     "4",
     "4",
     "4",
     "4",
     "5",
     "4"
   ]
 },
 {
   "name": "Jessica Jones",
   "photo": "./app/public/matchPhotos/photo6.jpg",
   "scores": [
     "4",
     "4",
     "4",
     "4",
     "4",
     "4",
     "4",
     "4",
     "5",
     "4"
   ]
 },
 {
   "name": "Jasmine Love",
   "photo": "./app/public/matchPhotos/photo7.jpg",
   "scores": [
     "4",
     "3",
     "3",
     "2",
     "2",
     "2",
     "2",
     "1",
     "2",
     "1"
   ]
 },
 {
   "name": "Sandra Smith",
   "photo": "./app/public/matchPhotos/photo8.jpg",
   "scores": [
     "1",
     "2",
     "2",
     "2",
     "4",
     "3",
     "4",
     "3",
     "3",
     "1"
   ]
 },
 {
   "name": "Kevin Hart",
   "photo": "./app/public/matchPhotos/photo9.jpg",
   "scores": [
     "5",
     "5",
     "3",
     "3",
     "2",
     "2",
     "5",
     "5",
     "4",
     "3"
   ]
 }
]

UPDATE 1

I am trying to incorporate the following code but am not understanding as to why I keep getting the following error:

ReferenceError: data is not defined

I believe it has to do with how I am trying to incorporate the incoming data. I took the code and tried to translate it to fit my code.

// Read the file and send to the callback
fs.readFileSync('./app/data/friends.json', findCompatibility); <---- This is the line I think is causing issues
// Write the callback function
function findCompatibility(data) {
   var results = [];
   for (let i = 0; i < data.length; i++) {
     for (let j = 1; j < data.length - 1; j++) {
       const user1 = data[i];
       const user2 = data[j];
       var difference = 0;
       for (let k = 0; k < user1.scores.length; k++) {
         difference += Math.abs(Number(user1.scores[k]) - Number(user2.scores[k]));
       }
       results.push({"name": user1.name, "friend": user2.name, "difference": difference});
     }
   }
   return results;
  }
  console.log(findCompatibility(data));
Jermaine Subia
  • 776
  • 1
  • 7
  • 31
  • Where exactly are you stuck? Is it the logic you're struggling with? Since you don't have to compare the arrays, just subtract numbers at the same index. 1) Create the persons scores, as shown. 2) Load the JSON file, as shown. 3) Loop over the all the users in the file. 4) For each person in the file, loop over the scores. Subtract each person score from the users score at the same index. 5) Sum those numbers, you now have the difference between the person and the user. 6) The person with the smallest difference, is the match. – Shilly Sep 25 '19 at 16:08

2 Answers2

1
var arr1 = [1,4,7,88,40];
var arr2 = [1,77,3,45];

function diff(a1, a2){
      var s1 = a1.reduce((red,n) => red+n);
      var s2 = a2.reduce((red,n) => red+n);

      var total = s1 - s2;

      return total >= 0 ? total : -1*total;
} 

console.log(diff(arr2, arr1));
Lee Developer
  • 98
  • 1
  • 7
1

Some pointers to point you in right direction:

  1. To ensure that differences aren't negative use Math.abs() to get the absolute value of the difference.
  2. Right now all the scores are strings, convert them to number using Number() or parseInt().

var data = [ { "name": "Mike Jackson", "photo": "./app/public/matchPhotos/photo0.jpg", "scores": [ "3", "2", "4", "3", "3", "4", "4", "4", "3", "4" ] }, { "name": "Jermaine Subia", "photo": "./app/public/matchPhotos/photo1.jpg", "scores": [ "4", "4", "2", "2", "4", "5", "3", "4", "5", "2" ] }, { "name": "Taji Gibson", "photo": "./app/public/matchPhotos/photo2.jpg", "scores": [ "1", "5", "3", "2", "3", "1", "3", "4", "3", "3" ] }, { "name": "Jamie Schully", "photo": "./app/public/matchPhotos/photo3.jpg", "scores": [ "5", "3", "3", "4", "2", "4", "4", "5", "5", "5" ] }, { "name": "Justin Andres", "photo": "./app/public/matchPhotos/photo4.jpg", "scores": [ "2", "1", "1", "1", "2", "3", "2", "2", "2", "4" ] }, { "name": "Austin Brooks", "photo": "./app/public/matchPhotos/photo5.jpg", "scores": [ "2", "3", "4", "2", "4", "4", "4", "4", "5", "4" ] }, { "name": "Jessica Jones", "photo": "./app/public/matchPhotos/photo6.jpg", "scores": [ "4", "4", "4", "4", "4", "4", "4", "4", "5", "4" ] }, { "name": "Jasmine Love", "photo": "./app/public/matchPhotos/photo7.jpg", "scores": [ "4", "3", "3", "2", "2", "2", "2", "1", "2", "1" ] }, { "name": "Sandra Smith", "photo": "./app/public/matchPhotos/photo8.jpg", "scores": [ "1", "2", "2", "2", "4", "3", "4", "3", "3", "1" ] }, { "name": "Kevin Hart", "photo": "./app/public/matchPhotos/photo9.jpg", "scores": [ "5", "5", "3", "3", "2", "2", "5", "5", "4", "3" ] } ];

function findCompatibility(data) {
  var results = [];

  for (let i = 0; i < data.length; i++) {
    for (let j = 1; j < data.length - 1; j++) {
      const user1 = data[i];
      const user2 = data[j];
      var difference = 0;

      for (let k = 0; k < user1.scores.length; k++) {
        difference += Math.abs(Number(user1.scores[k]) - Number(user2.scores[k]));
      }

      results.push({"name": user1.name, "friend": user2.name, "difference": difference});
    }
  }
  return results;
}

console.log(findCompatibility(data));
Nikhil
  • 6,493
  • 10
  • 31
  • 68
  • thank you! I am working on incorporating it into my code but I have to figure out why it is giving me an error at the for loop that contains user1.scores.length it is getting cannot read property of undefined.I will add update above so you can see. – Jermaine Subia Sep 25 '19 at 18:26
  • You're welcome @JermaineSubia. This error means one of the objects in your data is either `undefined` or doesn't have `scores` property. – Nikhil Sep 25 '19 at 18:32
  • @JermaineSubia - In your code in `handleFile()` function, call `findCompatibility(obj)` after `obj = JSON.parse(data)` statement. You should pass the parsed object `obj` to the function. – Nikhil Sep 25 '19 at 18:50
  • Perfect thank you now I just have to write out the code to have the perfect match print out. – Jermaine Subia Sep 25 '19 at 19:24