1. I have an array of strings (scores written in the form of fractions) e.g. ["40/60", "30/40", ...]. A score represents a user's response to a question and the array is all of the responses for a given category.

  2. I want to split the strings, parse each into an integer, then in a for loop add each left hand side fraction to get a total category score for a user, and add each right hand side fraction to get a total possible max score.

I've already tried the below code and am getting back NaN.

################
var scoreArray = ["45/60", "60/60", "40/40","30/40", "15/20", "30/40", "30/60", "20/40"];

var i;

var myCategoryScore;

var maxCategoryScore;
################

for(i=0; i < scoreArray.length;i++){

    var splitScore = scoreArray[i].split("/");
    console.log(splitScore);

    myQuestionScore = parseInt(splitScore[0], 10);
    myCategoryScore = myCategoryScore + myQuestionScore;
    console.log(myCategoryScore);

    maxQuestionScore = parseInt(splitScore[1]);
    maxCategoryScore = maxCategoryScore + maxQuestionScore; 
    console.log(maxCategoryScore);
}

The result printed is:

Array ["45", "60"]

NaN

NaN

Array ["60", "60"]

NaN

NaN

Array ["40", "40"]

NaN

NaN

etc

However when just printing out the parsed integers on their own its clear they have been correctly parsed...

for(i=0; i<scoreArray.length;i++){

   var splitScore = scoreArray[i].split("/");
   console.log(splitScore);

   myQuestionScore = parseInt(splitScore[0], 10);
   console.log(myQuestionScore);

   maxQuestionScore = parseInt(splitScore[1]);
   console.log(maxQuestionScore);
}

This results in..

Array ["45", "60"]

45

60

Array ["60", "60"]

60

60

Array ["40", "40"]

40

40

etc...

So why can I not add the total together? How do i fix it? Is due to scope?

Thanks!

3 Answers

2
Cid On Best Solutions

myCategoryScore is never initialized.

myCategoryScore = myCategoryScore + myQuestionScore; will provide undefined + 42 //NaN

The same for maxCategoryScore

How to reproduce your bug :

var UndefinedValue;

console.log(UndefinedValue);

console.log(UndefinedValue + 42);

Initialize your variables, so you can use them in mathematical operations :

var scoreArray = ["45/60", "60/60", "40/40","30/40", "15/20", "30/40", "30/60", "20/40"];

var i;
// initialize this one
var myCategoryScore = 0;
// and this one
var maxCategoryScore = 0;


for(i=0; i < scoreArray.length;i++){

    var splitScore = scoreArray[i].split("/");
    console.log(splitScore);

    myQuestionScore = parseInt(splitScore[0], 10);
    myCategoryScore = myCategoryScore + myQuestionScore;
    console.log(myCategoryScore);

    maxQuestionScore = parseInt(splitScore[1]);
    maxCategoryScore = maxCategoryScore + maxQuestionScore; 
    console.log(maxCategoryScore);
}

1
buffy On

I think the .reduce function would be a good choice here :)

var scoreArray = ["45/60", "60/60", "40/40","30/40", "15/20", "30/40", "30/60", "20/40"];
var scoreArrayParsed = scoreArray.reduce((acc, e) => {
    let arr = e.split('/');

    acc.min += parseInt(arr[0]);
    acc.max += parseInt(arr[1]);

    return acc;
}, {
    min: 0,
    max: 0
});

console.log(scoreArrayParsed);
0
Rafael Khan On

If you have lodash available, you can do the splitting step in a cool (or disgusting) one-line way using _.zip

Creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.

_.zip(['a', 'b'], [1, 2], [true, false]);
// => [['a', 1, true], ['b', 2, false]]

You can try this:

const _ = require('lodash');
const scoreArray = ["45/60", "60/60", "40/40","30/40", "15/20", "30/40", "30/60", "20/40"];
const sortedScores = _.zip(..._.map(scoreArray, s => s.split('/')));

// [ [ '45', '60', '40', '30', '15', '30', '30', '20' ],
//   [ '60', '60', '40', '40', '20', '40', '60', '40' ] ]

The first array has the first values, and the second well... has the second values! After this you can go ahead and use reduce as the other answers have suggested. Lodash also offers a _.sum function you can use to save a little overhead :)