Determine a winner with if / else - javascript

Can anyone help me out and explain to me how I can use operators inside an if / else statement, I am trying to do something simple and get a result of two different multiplications, I'm a self taught developer so please bear with me
var oscar = {
height: 155,
age: 22,
};
var andrew = {
height: 170,
age: 16,
};
if ((oscar * 5) > (andrew * 5)) {
console.log('Oscar is the winner');
} else if ((oscar * 5) < (andrew * 5)) {
console.log('Andrew is the winner')
} else {
console.log('No winner')
}

Variables are objects, you must specify the property of comparison.
No need to multiply by 5.
var oscar = {
height: 155,
age: 22
};
var andrew = {
height: 170,
age: 16
};
if ((oscar.height) > (andrew.height)) {
console.log('Oscar is the winner');
} else if ((oscar.height) < (andrew.height)) {
console.log('Andrew is the winner')
} else {
console.log('No winner')
}

You cannot compare objects like that.
Perhaps you wanted to assign some points? Then add another property which you CAN calculate on
Also no need to multiply by anything if you multiply both sides of the equal sign with the same number
You could do this:
function scoreIt(p1,p2) {
var diff = p1.points - p2.points;
console.log("diff", diff);
if (diff > 0) {
console.log(p1.name+ ' is the winner with ' + p1.points);
} else if (diff < 0) {
console.log(p2.name + ' is the winner with ' + p2.points);
} else {
console.log('No winner - tied score ' + p1.points);
}
}
var participant1 = {
name: "Oscar",
height: 155,
age: 22,
points: 8 // no trailing comma
};
var participant2 = {
name: "Andrew",
height: 170,
age: 16 // no trailing comma
};
// later somewhere:
participant2.points = 9; // assignment
scoreIt(participant1,participant2);
participant1.points += 5; // increase
scoreIt(participant1,participant2);
participant2.points += 4;
scoreIt(participant1,participant2);
The object would be even better if you use the names as keys:
var participants = {
"Oscar": {
height: 155,
age: 22,
points: 8 // no trailing comma
},
"Andrew" : {
height: 170,
age: 16 // no trailing comma
}
}

Related

How Can I Subtract The Value Of A Object By The Value Of Another Object?

I'm new to coding so I might not have the best code but I have a object called computer and another called player. I want to subtract the value of the computers health by the value of the players attack power. Here is the code I currently have:
var player = {
health: 100,
attackPower: function () {
return Math.round(Math.random() * 10)
},
turnId: 0
}
var computer = {
health: 1,
attackPower: function () {
return Math.round(Math.random() * 10)
},
turnId: 1
}
function playerAttack() {
computer.forEach(e => e.health -= player.attackPower)
console.log(computer.health)
}
function computerChoice() {
ranNum = Math.round(Math.random() * 2)
if (ranNum == 1) {
return player.health - computer.attackPower
} else if (ranNum == 2) {
return computer.health + computer.attackPower
}
}
Any help will be appreciated
Thanks

Running a function on an Array of Arrays - js

I am trying to take the average of 3 grades for three student (stored in an array of arrays), and then run those averages through a function with an else if statement to check whether the average grades are each and A,B or C.
I would prefer not to have to make a separate function with an else if for each students average (so I would know how to scale this to more than 3 inputs), and I am not sure how I can index the averageGrades array in the function so that I can console.log each element (student) of the averageGrades array and have the else if statement evaluate that particular element (student).
I also tried making an averageGrade variable for each student so that the averageGrades array had single values and not a full equation but ran into the same problem.
var studentGrades = [
[80, 90, 94],
[80, 90, 94],
[80, 90, 94]
]
var studentAvgerages = [
(studentGrades[0][0] + studentGrades[0][1] + studentGrades[0][2]) / 3,
(studentGrades[1][0] + studentGrades[1][1] + studentGrades[1][2]) / 3,
(studentGrades[2][0] + studentGrades[2][1] + studentGrades[2][2]) / 3
]
for (var i = 0; i <= studentAvgerages.length; i++) {
function evalGrades(studentAvgerages[i]) {
if (studentAvgerages[i] >= 90) {
return "A"
} else if ((studentAvgerages[i] >= 80) && (studentAvgerages[i] < 90)) {
return "B"
} else if ((studentAvgerages[i] >= 70) && (studentAvgerages[i] < 80)) {
return "C"
} else {
return "Failed"
}
}
}
console.log(evalGrades(studentAvgerages[0]))
console.log(evalGrades(studentAvgerages[1]))
console.log(evalGrades(studentAvgerages[2]))
Thought I knew what you were looking for, less sure now, but hope this helps a little, somehow? As others have shown, there are some one liners to arrive at your average, if that's what you want.
var studentGrades = [
[80, 90, 94],
[80, 90, 94],
[80, 90, 94]
]
for(var i=0; i < studentGrades.length; i++){
var avg = 0;
for(var j=0; j < studentGrades[i].length; j++){
avg += studentGrades[i][j];
}
avg = avg/studentGrades[i].length;
switch(true){
case (avg >= 90):
console.log("A");
break;
case (avg >= 80):
console.log("B");
break;
case (avg >= 70):
console.log("C");
break;
case (avg >= 60):
console.log("D");
break;
default:
"Failed";
break;
}
}
I prefer switch...case for tasks like this a lot of times, but don't forget to take into account performance. On an array of 20,000 sets of 200 student grades, might be worth using if/else to maintain speed of page. See this answer for more details.
You could take an exit early approach fro getting the grade. No else parts are necessary bycause of the return statement.
For getting the average, you could take a dynamic approach with adding values and divide by the length of the array.
const
add = (a, b) => a + b,
getAverage = array => array.reduce(add, 0) / array.length,
evalGrades = grade => {
if (grade >= 90) return "A";
if (grade >= 80) return "B";
if (grade >= 70) return "C";
return "Failed";
},
studentGrades = [[80, 90, 94], [80, 70, 60], [76, 82, 91]],
studentAvgerages = studentGrades.map(getAverage);
console.log(...studentAvgerages);
console.log(...studentAvgerages.map(evalGrades));
If you are new at programming or javascript, practice some basic examples first and try to understand how the code should be structured in a way you can manage and reuse it. Basically functional programming at least.
From what I understood from your code, you need something that can dynamically calculate the grades of the students.
I have re rewritten the code hope that helps. Also, try to debug the code on your own so as to figure out how the code flows.
var studentGrades = [
[80, 90, 94],
[80, 90, 94],
[80, 90, 94]
]
function evalGrades(grades) {
var sum = 0;
for(var i =0; i<grades.length; i++){
sum = sum + grades[i];
}
var avg = sum/grades.length;
if (avg >= 90) {
return "A"
} else if ((avg >= 80) && (avg < 90)) {
return "B"
} else if ((avg >= 70) && (avg < 80)) {
return "C"
} else {
return "Failed"
}
}
for (var i = 0; i < studentGrades.length; i++) {
console.log(evalGrades(studentGrades[i]))
}
Try this. I hope I've been helpful.
var studentGrades = [
[80, 90, 94],
[80, 90, 94],
[80, 90, 94]
]
for (var i = 0; i < studentGrades.length; i++) {
var average = studentGrades[i].reduce((a, b) => a + b, 0) / studentGrades[i].length;
if (average >= 90) { var result = "A" }
else if ( average >= 80 && average < 90 ) { var result = "B" }
else if ( average >= 70 && average < 80 ) { var result = "C" }
else { var result = "Failed" }
console.log(result);
}

Elegant solution for determining which range a numeric value falls into

If I supply a number to a function, how would I go about validating it against a range of numbers like this?
1-10 = A
11-20 = B
21-30 = C
...
I know I can do if statements to evaluate this, but I'm looking for something more elegant because the problem gets a lot more complex and I don't want a nasty web of ifs.
var letter = "";
function getLetter(num) {
if (num >= 1 && num <= 10) {
letter = "A";
} else if (num >= 11 && num <= 20) {
letter = "B";
}
// this eventually gets gross
}
Expected outcome of getLetter(14) would be "B", and getLetter(49) would be "E", etc. Case/switch is also off the table for similar reasons.
Any other ideas welcome.
Just a point about your code
function getLetter(num) {
if (num >= 1 && num <= 10) {
letter = "A";
} else if (num >= 11 && num <= 20) {
letter = "B";
}
// this eventually gets gross
}
this can be simplified to
function getLetter(num) {
if (num >= 1) {
if(num <= 10) {
letter = "A";
} else if (num <= 20) {
letter = "B";
}
// this eventually gets gross too
}
}
But:
If it's as simple as every letter represents a range of 10 values:
function getLetter(num) {
return String.fromCharCode(65 + Math.floor((num - 1) / 10));
}
console.log(getLetter(1));
console.log(getLetter(14));
console.log(getLetter(49));
or as suggested
function getLetter(num) {
const ret = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return ret[Math.floor((num - 1) / 10)] || "+"; // greater than 260
}
console.log(getLetter(1));
console.log(getLetter(14));
console.log(getLetter(49));
console.log(getLetter(261));
function getLetter(number) {
let ranges = {
a: 10,
b: 20,
c: 30,
underflow: 0,
overflow: Infinity
}
return Object.entries(ranges)
.sort(([ka, va], [kb, vb]) => va - vb) // because object key sort order isn't guaranteed
// though it will be in the order as declared, but
// sorting makes sense
.find(([key, value]) => number <= value)[0];
}
console.log(getLetter(5))
console.log(getLetter(17))
console.log(getLetter(20))
console.log(getLetter(30))
console.log(getLetter(31))
console.log(getLetter(0))
If the ranges are contiguous, you only need one of the boundaries
Works alright if you want to put your ranges into an object, and then loop through that
function getLetter (number) {
let ranges = {
a: [1, 10],
b: [11, 20],
c: [21, 30],
d: [31, 36],
e: [37, 40]
}
return Object.keys(ranges).find((key) => {
let currRange = ranges[key];
if (number >= currRange[0] && number <= currRange[1]) {
return key;
}
});
}
console.log(getLetter(5))
console.log(getLetter(17))
console.log(getLetter(20))
console.log(getLetter(30))
console.log(getLetter(35))
console.log(getLetter(39))

How can I create an array with return result of a function?

I created a simple calculator
johnRestBill = [124, 48, 268, 180, 42]; //dollar
function tipCal(){
for(var i = 0; i < johnRestBill.length; i++){
if (johnRestBill[i] < 50) {
console.log(johnRestBill[i] * .2);
} else if (johnRestBill[i] >= 50 && johnRestBill[i] <= 200){
console.log(johnRestBill[i] * .15);
} else {
console.log(johnRestBill[i] * .1);
}
}
}
return tipCal();
I got the result of each index of johnRestBill array and now I want to make an array with the result.
So I made var tips = [] and typed tips.push(tipCal()) but it is not working and I don't know why...
To create tips, it would be much more appropriate to use .map instead, and for that, you need a function that returns the calculated tip:
const johnRestBill = [124, 48, 268, 180, 42];
function tipCal(bill) {
if (bill < 50) return bill * .2;
else if (bill >= 50 && bill <= 200) return bill * .15;
else return bill * .1;
}
const tips = johnRestBill.map(tipCal);
console.log(tips);
You can use array map method and return the same logical conditions
var johnRestBill = [124, 48, 268, 180, 42]; //dollar
// map returns a new array
let arr = johnRestBill.map(function(item) {
if (item < 50) {
return item * .2;
} else if (item >= 50 && item <= 200) {
return item * .15;
} else {
return item * .1;
}
})
console.log(arr)

Check values of nested items of object

I am trying to check the week object's minutes and hours and I cannot figure out what I am doing wrong. The week object can contain variations of Day1 - Day7 so I dont want to check them specifically. I want to check the nested Hours/Minutes. I also don't want to use jquery and it has to work with ie8. Any help would be greatly appreciated.
week = {
Day1: {
Hours: 6,
Minutes: 20
},
Day2: {
Minutes: 45
},
Day3: {
Hours: 8,
Minutes: 15
}
};
hoursInValid = false;
minutesInValid = false;
for (var item in week) {
if (week.hasOwnProperty(item)) {
for (var i = 0; i < week[item].length; i++ )
{
if (week[item][i].Hours > 6) {
hoursInValid = true;
break;
}
if (week[item][i].Minutes > 20) {
minutesInValid = true;
break;
}
}
}
}
I don't see the need for the internal for loop. This is the solution I came up with. I added checks to make sure the DayN objects have Hours and Minutes properties.
week = {
Day1: {
Hours: 6,
Minutes: 20
},
Day2: {
Minutes: 45
},
Day3: {
Hours: 8,
Minutes: 15
}
};
hoursInValid = false;
minutesInValid = false;
for (var item in week) {
if (week[item].hasOwnProperty('Hours')) {
if (week[item].Hours > 6) {
hoursInValid = true;
break;
}
}
if (week[item].hasOwnProperty('Minutes')) {
if (week[item].Minutes > 20) {
minutesInValid = true;
break;
}
}
}
Try this:
for (var day in week) {
for (var unit in week[day]) {
if (unit === 'Hours' && week[day][unit] > 6) {
hoursInvalid = true;
} else if (unit === 'Minutes' && week[day][unit] > 20) {
minutesInvalid = true;
}
}
}
The break statements may not allow you to iterate over all the properties.
Do this instead:
var invalidHours = {}, invalidMinutes = {};
for(var i in week){
var w = week[i];
if(w.hasOwnProperty('Hours')){
invalidHours[i] = w.Hours > 6 ? true : false;
}
else{
// no hours
}
if(w.hasOwnProperty('Minutes')){
invalidMinutes[i] = w.Minutes > 20 ? true : false;
}
else{
// no minutes
}
}
if(invalidHours.Day1) // day 1 hours are invalid
if(invalidMinutes.Day2) // day 2 minutes are invalid

Categories