I created a multidimensional array:
var students = [ [['David'], [80]], [['Vinoth'], [77]], [['Goren'],[55]] ];
Then I created an if statement that will test if the student's grade is F to A.
for (var i = 0; i < students.length; i++) {
for (var j = 1; j < students.length; j++) {
document.write(students[i][j] + "<br/>");
if (students[i][j] < 60) {
document.write(students[i][j] + " is Grade : F");
} else if (students[i][j] < 70) {
document.write(students[i][j] + " is Grade : D");
} else if (students[i][j] < 80) {
document.write(students[i][j] + " is Grade : C");
} else if (students[i][j] < 90) {
document.write(students[i][j] + " is Grade : B");
} else if (students[i][j] < 100) {
document.write(students[i][j] + " is Grade : A");
}
}
}
In my pursuit to output the name of the student and the grade, I even ended up creating three for loops, which did not work.
I was wondering how can I achieve this output:
David's grade is 80 and is C Grade.
Vinoth's grade is 77 and is C Grade.
Goren's grade is 55 and is F Grade.
What am I missing?
7 Answers 7
Other answers have suggested simplifying your array structure. If you really want to use your extra nesting, you need to do an extra level of indexing. But you don't need nested loops, because it's still just a linear structure.
for (var i = 0; i < students.length; i++) {
var student = students[i][0][0];
var score = students[i][1][0];
var grade;
if (score < 60) {
grade = "F";
} else if (score < 70) {
grade = "D";
} else if (score < 80) {
grade = "C";
} else if (score < 90) {
grade = "B";
} else if (score < 100) {
grade = "A";
}
document.write(student + "'s score is " + score + ' and is Grade ' + grade + '<br>');
}
Also, if you expect a score of 80 to generate a C grade rather than B, you should be using <= rather than < in the comparisons.
As a general rule, I recommend using objects rather than arrays for heterogeneous data, so your array should be like:
var students = [ {
name: 'David',
score: 80
}, {
name: 'Vinoth',
score: 77
}, {
name: 'Goren',
score: 55
}];
Then you use students[i].name and students[i].score, which is much easier to understand.
The idea is that you use arrays for collections of things that are all the same type, and objects for collections of related information about a thing.
Your data is structure is strange in that it is deeply nested.
I would transform it to the shallower:
var students = [ [ 'David', 80], ['Vinoth', 77], ['Goren', 55] ];
It would be better to define a single argument function for determining the grade letter:
function getGrade(value) {
if (value > 90) return 'A';
else if (value > 80) return 'B';
else if (value > 70) return 'C';
else if (value > 60) return 'D';
else return 'F'
}
I would prefer a forEach loop but since you seem to have a preference for the for, we can write:
for (let i = 0; i < students.length; i++) {
console.log(`${students[i][0]}'s grade is ${students[i][1]} and is a ${getGrade(students[i][1])} Grade`);
}
2 Comments
Your array is 3 level nested. So you might want to run 3 loops. However the second level has only 2 elements and the third level has only 1 element. So you can run only 1 loop. See the following working snippet.
var students = [ [['David'], [80]], [['Vinoth'], [77]], [['Goren'],[55]] ];
for (var i = 0; i < students.length; i++) {
document.write(students[i][0][0] + " ");
if (students[i][1][0] < 60) {
document.write(students[i][1][0] + " is Grade : F" + "<br/>");
} else if (students[i][1][0] < 70) {
document.write(students[i][1][0] + " is Grade : D"+ "<br/>");
} else if (students[i][1][0] < 80) {
document.write(students[i][1][0] + " is Grade : C"+ "<br/>");
} else if (students[i][1][0] < 90) {
document.write(students[i][1][0] + " is Grade : B"+ "<br/>");
} else if (students[i][1][0] < 100) {
document.write(students[i][1][0] + " is Grade : A"+ "<br/>");
}
}
Comments
If you really, REALLY want to just fix your solution with just the minimum modifications without touching your data, then you were missing 3 things to get the output you wanted:
document.write("<br>")at the end- inner loop until
students.length - 1 - name of stundent accessed as
students[i][j - 1]
Here's the complete fixed code, run it by clicking "Run code snippet" at the bottom
var students = [ [['David'], [80]], [['Vinoth'], [77]], [['Goren'],[55]] ];
for (var i = 0; i < students.length; i++) {
for (var j = 1; j < students.length - 1; j++) {
document.write(students[i][j - 1] + "'s grade is ");
if (students[i][j] < 60) {
document.write(students[i][j] + " and is Grade : F");
} else if (students[i][j] < 70) {
document.write(students[i][j] + " and is Grade : D");
} else if (students[i][j] < 80) {
document.write(students[i][j] + " and is Grade : C");
} else if (students[i][j] < 90) {
document.write(students[i][j] + " and is Grade : B");
} else if (students[i][j] < 100) {
document.write(students[i][j] + " and is Grade : A");
}
}
document.write("<br>")
}
Comments
Your students array's inner elements such as name or grade are themselves wrapped in brackets and thus become arrays. Remove the inner brackets.
Also, your comparison operator < should become <= if you want a score of 80 to be rated as a 'C' as per your example.
let students = [['David', 80], ['Vinoth', 77], ['Goren', 55]];
// Define rating function:
let rate = (grade) => grade <= 60 ? 'F' : grade <= 70 ? 'D' : grade <= 80 ? 'C' : grade <= 90 ? 'B' : 'A';
// Map students to phrases:
let phrases = students.map((student) => `${student[0]}'s grade is ${student[1]} and is ${rate(student[1])} grade.`);
// Output DOM nodes:
phrases.forEach((phrase) => {
let el = document.createElement('div');
el.textContent = phrase;
document.body.appendChild(el);
});
Comments
Array of objects is a better data structure for this particular case. Plus I have separated the score to grade conversion to a function, which makes code easier to read and reason about.
function getGrade (score) {
var grades = [
{
letter: 'A',
minScore: 90
},
{
letter: 'B',
minScore: 80
},
{
letter: 'C',
minScore: 70
},
{
letter: 'D',
minScore: 60
},
{
letter: 'F',
minScore: 0
}
];
for (var i = 0; i < grades.length; i++) {
if (grades[i].minScore <= score) return grades[i].letter;
}
}
var students = [
{
name: 'David',
score: 80
},
{
name: 'Vinoth',
score: 77
},
{
name: 'Goren',
score: 55
}
];
students.forEach(function (student) {
var str = student.name +
"'s score is " +
student.score +
" and is " +
getGrade(student.score) +
" Grade.";
console.log(str);
});
Comments
I hope this will works for you
var students = [ [['David'], [80]], [['Vinoth'], [77]], [['Goren'],[55]] ];
for (var i = 0; i < students.length; i++) {
document.write("<br/>"+students[i][0] + "'s");
for (var j = 1; j < students.length; j++) { console.log(students[i][0]);
if (students[i][j] < 60) {
document.write(students[i][j] + " is Grade : F");
}
else if (students[i][j] < 70) {
document.write(students[i][j] + " is Grade : D");
} else if (students[i][j] < 80) {
document.write(students[i][j] + " is Grade : C");
} else if (students[i][j] < 90) {
document.write(students[i][j] + " is Grade : B");
} else if (students[i][j] < 100) {
document.write(students[i][j] + " is Grade : A");
}
} }
students.lengthas the limit for bothforloops?