My question is about using Javascript to do triangle evaluation by its sides. The following code is very initial version even it works. I'd like to know whether it could be more simplifying or there is other way to achieve the same result.
Thanks!
let a = Number(prompt('Please input the the first side (a)'))
let b = Number(prompt('Please input the the second side (b)'))
let c = Number(prompt('Please input the the third side (c)'))
if (a + b <= c || b + c <= a || c + a <= b || Number.isNaN(a) || Number.isNaN(b) || Number.isNaN(c) || a == "" || b == "" || c == ""){
console.log("invalid")
}
else if ((a > 0 && b >0 && c >0 ) && (a == b && b == c && c == a)){
console.log("equilateral triangle")
}
else if ((a > 0 && b >0 && c >0 ) && (a == b || b == c || c == a)){
console.log("isosceles triangle")
}
else {
console.log("scalene triangle")
}
Another way could be to explicitly convert the lengths to a number (0 for NaN) and sort them first. And a ternary operator can be useful here also:
let [d, e, f] = [a, b, c].map(a => +a || 0).sort((a, b) => a-b);
let result = d + e <= f ? "invalid"
: d === f ? "equilateral"
: d < e && e < f ? "scalene"
: "isosceles";
console.log(result);
This will not be the fastest when doing many thousands of them, but I like the look of it.
[a, b, c]
turns the three values into an array.
.map
is a method available for arrays. For each original value in [a, b, c]
the following (arrow) function is executed,
a => +a || 0
map
creates a new array consisting of the results of calling that function on each separate value (so first with a
, then with b
and finally with c
)
+a
uses the unary plus as a short way of turning a value into a number, which means that you could omit the Number()
calls you did in the first three lines of your code. When the result of this is NaN
or 0, then || 0
will kick in: instead of NaN
or 0, 0 will be taken instead (||
is a logical OR operator and 0 will only be used when the left side is considered "falsy"). This practically means that NaN
is replaced by 0.
So up to now the code has roughly done something similar to the following:
let newarray = [];
newarray[0] = +a;
if (Number.isNaN(newarray[0])) newarray[0] = 0;
newarray[1] = +b;
if (Number.isNaN(newarray[1])) newarray[1] = 0;
newarray[2] = +c;
if (Number.isNaN(newarray[2])) newarray[2] = 0;
Then another array method is called on that array returned by .map()
: the method .sort()
. That method will use the provided callback function (a, b) => a-b
to make comparisons in the array and sort it based on the values returned by such calls. It is up to the sort
method to decide for which pairs this function is called. When the returned value is negative, it means the compared values are already in increasing order. When positive, they should be rearranged. When zero, they should be considered equal to the sort algorithm.
So... we now have an array that consists of numbers which are guaranteed to no longer have a NaN
, and which are sorted in ascending order.
Then that array is assigned using so-called destructuring:
let [d, e, f] =
This means that the individual values of the sorted array are assigned one by one to three new variables. So this is roughly short for:
let d = new_sorted_array[0];
let e = new_sorted_array[1];
let f = new_sorted_array[2];
Because these values are now ordered, we can use them for much simpler comparisons to decide on the shape of the triangle. What follows is an expression using a chain of ternary operators which much resemble an if (...) ... else if ...
chain. So:
let result = d + e <= f ? "invalid"
: d === f ? "equilateral"
: d < e && e < f ? "scalene"
: "isosceles";
... is short for this:
let result;
if (d + e <= f) result ="invalid"
else if (d === f) result = "equilateral"
else if (d < e && e < f) result = "scalene"
else result = "isosceles";