Given an object containing the number of positive and negative reviews, for example { positive: 24, negative: 8 }, return the review positivity score.
function getReviewPositivityScore (positive, negative) {
let a = positive;
let b = negative;
let result = a - b ;
return result;
}
module.exports = getReviewPositivityScore;
Error message I get:
getReviewPositivityScore
1) should return the number of positive reviews minus the number of negative reviews
0 passing (6ms)
1 failing
getReviewPositivityScore
should return the number of positive reviews minus the number of negative reviews:
AssertionError: expected NaN to deeply equal 16
expected - actual
-NaN
+16
at Context. (.guides/secure/test3.5.1.js:8:17)
at processImmediate (internal/timers.js:439:21)
Since you are passing an object you only need one parameter as function input, and then access the values from it:
function getReviewPositivityScore (object) {
return object.positive - object.negative;
}
Related
I need a function that will take an array of numbers, and which will return an array that only retains the numbers that are unique in their digit sequence, i.e. that only occur once even if you would reverse their digits.
This is my code so far:
var a=[5,8,3,8,3,7,5,12,21];
console.log(a);
let output=[...new Set([...a])] // it removes the repeated data...
console.log(output);
This works for the numbers 3, 8 and 5, whose duplicates are removed, but the value 21 should also be removed, because there is already 12, which is 21 with the digits in reversed order.
How can I achieve that?
The expected output for the above example is:
[5,8,3,7,12]
My code returns:
[5,8,3,7,12,21]
You need (of course) to include the logic of reversing digits in a number.
I will assume that when the rightmost digit of a number is 0, that the reversal of that number is not defined. So the reversal of 19 is 91, but the reversal of 190 is not 91, but undefined (or NaN).
First define a function for that reversal of digits, and then use the idea of building a set:
function reverseDigits(num) {
// A Number should not have 0 as first digit
// unless it is 0
if (num && num % 10 == 0) return NaN;
return +[...String(num)].reverse().join("");
}
function specialUnique(a) {
const set = new Set;
for (const value of a) {
if (!set.has(value) && !set.has(reverseDigits(value))) {
set.add(value);
}
}
return [...set];
}
// Example input
const a = [5,8,3,8,3,7,5,12,21];
const output = specialUnique(a);
console.log(output);
You can use the filter.
let valueToRemove = 21;
output = output.filter((item) => item !== valueToRemove);
I want to recursively sum an integer: to split an integer into an array and then sum the individual items until I am left with a single integer array.
This is my logic:
Take an integer (n) and split it into an array.
Sum all the individual numbers.
Is the number greater than 9?
YES: Repeat steps 1 and 2
NO: Return the number
function digital_root(n) {
let digits = (""+n).split("").map(Number);
while (digits.length > 1) {
let result = digits.reduce((sum, int) => sum + int);
let digits = (""+result).split("").map(Number);
}
return digits;
};
This is the error code my Node.js chucks at me (at line 4 in the example code above):
ReferenceError: digits is not defined
at digital_root (repl:6:18)
I'm assuming that the variable digits is accessible inside the scope of the while loop, but obviously, I seem to be wrong? Could someone shed some insight here for me, please?
EDIT: Thank you everyone for your help! I've solved the issue.
For your curiosity, this is the mathematical form underlying my algorithm:
http://mathworld.wolfram.com/DigitalRoot.html
It could also have been solved in one line:
function digital_root(n) {
return (n - 1) % 9 + 1;
}
The inner let for digits (line 5) should be removed
function digital_root(n) {
let digits = (""+n).split("").map(Number);
while (digits.length > 1) {
let result = digits.reduce((sum, int) => sum + int);
digits = (""+result).split("").map(Number);
}
return digits;
}
Issue is let keyword, as let has block level scope, "digits" is not defined at the start of the while loop
Removing let for digits in while loop
function digital_root(n) {
let digits = (""+n).split("").map(Number);
while (digits.length > 1) {
let result = digits.reduce((sum, int) => sum + int);
digits = (""+result).split("").map(Number);
}
return digits;
}
console.log(digital_root(47))
Don't set digits in that manner, the digits inside of the loop should not have let in front of it because you have already defined digits outside the loop.
This will give you the result you expect:
digital_root = n => (Array.from(`${n}`)).reduce((sum, val) => sum + ~~val, 0);
console.log(digital_root(12345));
Hope this helps,
I am really curious how these functions actually work? I know there are a lot of questions about how to use these, I already know how to use them, but I couldn't find anywhere how to actually go about implementing this functionality on an array, for example, if there were no such functions? How would you code such a function if there were no helpers?
Here is the Math.max code in Chrome V8 engine.
function MathMax(arg1, arg2) { // length == 2
var length = %_ArgumentsLength();
if (length == 2) {
arg1 = TO_NUMBER(arg1);
arg2 = TO_NUMBER(arg2);
if (arg2 > arg1) return arg2;
if (arg1 > arg2) return arg1;
if (arg1 == arg2) {
// Make sure -0 is considered less than +0.
return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1;
}
// All comparisons failed, one of the arguments must be NaN.
return NaN;
}
var r = -INFINITY;
for (var i = 0; i < length; i++) {
var n = %_Arguments(i);
n = TO_NUMBER(n);
// Make sure +0 is considered greater than -0.
if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) {
r = n;
}
}
return r;
}
Here is the repository.
Below is how to implement the functions if Math.min() and Math.max() did not exist.
Functions have an arguments object, which you can iterate through to get its values.
It's important to note that Math.min() with no arguments returns Infinity, and Math.max() with no arguments returns -Infinity.
function min() {
var result= Infinity;
for(var i in arguments) {
if(arguments[i] < result) {
result = arguments[i];
}
}
return result;
}
function max() {
var result= -Infinity;
for(var i in arguments) {
if(arguments[i] > result) {
result = arguments[i];
}
}
return result;
}
//Tests
console.log(min(5,3,-2,4,14)); //-2
console.log(Math.min(5,3,-2,4,14)); //-2
console.log(max(5,3,-2,4,14)); //14
console.log(Math.max(5,3,-2,4,14)); //14
console.log(min()); //Infinity
console.log(Math.min()); //Infinity
console.log(max()); //-Infinity
console.log(Math.max()); //-Infinity
Let's take a look at the specifications (which could/should help you in implementation!)
In ECMAScript 1st Edition (ECMA-262) (the initial definitions for both Math.max/min), we see the following:
15.8.2.11 max(x, y)
Returns the larger of the two arguments.
• If either argument is NaN, the result is NaN.
• If x>y, the result is x.
• If y>x, the result is y.
• If x is +0 and y is +0, the result is +0.
• If x is +0 and y is −0, the result is +0.
• If x is −0 and y is +0, the result is +0.
• If x is −0 and y is −0, the result is −0.
15.8.2.12 min(x, y)
Returns the smaller of the two arguments.
• If either argument is NaN, the result is NaN.
• If x<y, the result is x.
• If y<x, the result is y.
• If x is +0 and y is +0, the result is +0.
• If x is +0 and y is −0, the result is −0.
• If x is −0 and y is +0, the result is −0.
• If x is −0 and y is −0, the result is −0.
Later versions of the specification give us:
ECMAScript 5.1
15.8.2.11 max ( [ value1 [ , value2 [ , … ] ] ] )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values.
• If no arguments are given, the result is −∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the largest value is done as in 11.8.5 except that +0 is considered to be larger than −0.
The length property of the max method is 2.
15.8.2.12 min ( [ value1 [ , value2 [ , … ] ] ] )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values.
• If no arguments are given, the result is +∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the smallest value is done as in 11.8.5 except that +0 is considered to be larger than −0.
The length property of the min method is 2.
The reference to 11.8.5 can be found here: The Abstract Relational Comparison Algorithm
ECMAScript 2015
20.2.2.24 Math.max ( value1, value2 , …values )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values.
• If no arguments are given, the result is −∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the largest value is done using the Abstract Relational Comparison algorithm (7.2.11) except that +0 is considered to be larger than −0.
The length property of the max method is 2.
20.2.2.25 Math.min ( value1, value2 , …values )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values.
• If no arguments are given, the result is +∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the smallest value is done using the Abstract Relational Comparison algorithm (7.2.11) except that +0 is considered to be larger than −0.
The length property of the min method is 2.
And again, 7.2.11 can be found here: Abstract Relational Comparison
Basic functionality:
Math.max() and Math.min() are used on numbers (or what they can coerce into numbers) you cannot directly pass an array as a parameter.
Ex:
Math.max(1,52,28)
You can have an number of comma delimited numbers.
Arrays:
This example shows how one could apply them to arrays:
JavaScript: min & max Array values?
Basically the following works:
Math.max.apply(null, [1,5,2,3]);
Why that works?
This works because apply is a function that all functions have which applies a function with the arguments of an array.
Math.max.apply(null, [1,5,2,3]) is the same as Math.max(1,5,2,3)
Well, here's min without Math.min (code is in ES6).
function min() {
return Array.from(arguments).reduce(
(minSoFar, next) => minSoFar < next ? minSoFar : next
, Infinity)
}
The same logic could be implemented with a simple loop. You would just need to keep track of one of variable through your iteration, which is the lowest value you've seen so far. The initial value of minSoFar would be Infinity. The reason is that any Number except Infinity is less than Infinity, but in the case of no arguments sent, we want to return Infinity itself, because that's what Math.min() with no arguments evaluates to.
function min() {
let minSoFar = Infinity
for(let i = 0, l = arguments.length; i < l; i++) {
const next = arguments[i]
minSoFar = minSoFar < next ? minSoFar : next
}
return minSoFar
}
Max can be implemented with pretty much the same logic, only you're keeping track of the highest value you've seen so far, and the initial value is -Infinity.
This is easy to implement with Array.prototype.reduce:
function min() {
var args = Array.prototype.slice.call(arguments);
var minValue = args.reduce(function(currentMin, nextNum) {
if (nextNum < currentMin) {
// nextNum is less than currentMin, so we return num
// which will replace currentMin with nextNum
return nextNum;
}
else {
return currentMin;
}
}, Infinity);
return minValue;
}
Here is the implementation of Math.min and Math.max from a real Javascript engine
Math.max : https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L78-L102
Math.min : https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L105-L129
How can I determine if a number is too big (will cause rounding errors if math is performed) in JavaScript.
For example, I have a function that formats percentages. If it cannot format the passed in value correctly, I want it to return the value exactly as it was passed in.
function formatPercent(x, decimals) {
var n = parseFloat(x); // Parse (string or number)
if ($.isNumeric(n) === false) {
return x; // Return original if not a number
} else {
return n.toFixed(decimals) + '%'; // Return formatted string
}
};
alert(formatPercent(276403573577891842, 2)); // returns 276403573577891840.00%
Since formatting such a huge number is a corner case and not expected, I'd prefer to just return the number as it was passed in. What is the limit before the rounding errors start and how would I check for them?
Update:
What is JavaScript's highest integer value that a Number can go to without losing precision? says precision works up to +/- 9007199254740992. I am testing to see if that is all I need to check against to safely fail and return the passed in value unmodified.
If you always pass x in as a string, that will ensure that there are no rounding errors. The problem is that 276403573577891842 is being rounded right as the number literal is parsed, but if you use strings, that will never happen. Try doing this:
function formatPercent(x, decimals) {
if(typeof x != "string" && typeof x != "number") return x;
x = x+"";//convert to string if it is a number
var r = /^(?:(\d+)(\.\d*)?|(\d*)(\.\d+))$/;// RegExp for matching numerical strings
return x.replace(r, function(match, int, dec){
if(decimals>0){
int = (typeof int == "string"?int:"");//if passed string didn't have integers
dec = (typeof dec == "string"?dec:".");//if passed string didn't have decimals
while(dec.length-1<decimals) dec += "0";//pad zeroes until dec.length-1==decimals
return int+dec.slice(0,decimals+1)+"%";//in case dec.length-1>decimals
}
int = (typeof int == "string"?int:"0");//if passed string didn't have integers
return int+"%";
});
// Return formatted string or original string conversion if no match found
}
alert(formatPercent("276403573577891842", 1));// returns 276403573577891842.0%
alert(formatPercent("276403573577891842.55", 1));// returns 276403573577891842.5%
alert(formatPercent("276403573577891842.55", 0));// returns 276403573577891842%
alert(formatPercent(".55", 1));//returns .5%
alert(formatPercent(".55", 0));//returns 0%
alert(formatPercent(276403573577891842, 1));// returns 276403573577891840.0%
alert(formatPercent("this is not a number", 2));// returns this is not a number
alert(formatPercent({key:"not number or string"}, 2));// returns the object as it was
Even though formatPercent still fails in the case of passing a number, this will prevent rounding error from passed strings. Please note this is not incorrect, as the only case in which it will fail is when a number that is too large is hard-coded as a parameter.
function formatPercent(x, decimals) {
var n = parseFloat(x); // Parse (string or number)
if ($.isNumeric(n) === false) {
return x; // Return original if not a number
} else {
var d = Math.pow(10, decimals)
return (Math.round(n * d) / d).toString() + "%";
}
};
Using rounding will drop the decimal if it's .00
This is what I used to catch too big or too small integers:
function getSafeNumber(x) {
var n = parseFloat(x); // Parse and return a floating point number
if ($.isNumeric(n) === false ||
n >= 9007199254740992 ||
n <= -9007199254740992) {
return false; // Not numeric or too big or too small
} else {
return n; // return as number
}
};
No greater than nine quardbillion will cause this type of error due to internal representation of no
This question already has answers here:
issue with comparing two numbers in javascript
(5 answers)
Closed 4 months ago.
I have this javascript function to validate if a number is greater than another number
function validateForm() {
var x = document.forms["frmOrder"]["txtTotal"].value;
var y = document.forms["frmOrder"]["totalpoints"].value;
if (x > y) {
alert("Sorry, you don't have enough points");
return false;
}
}
It's not working for some reason.
If I do alert(x) I get 1300, and alert(y) gives 999
This works....
function validateForm() {
var x = 1300;
var y = 999;
if (x > y) {
alert("Sorry, you don't have enough points");
return false;
}
}
You should convert them to number before compare.
Try:
if (+x > +y) {
//...
}
or
if (Number(x) > Number(y)) {
// ...
}
Note: parseFloat and pareseInt(for compare integer, and you need to specify the radix) will give you NaN for an empty string, compare with NaN will always be false, If you don't want to treat empty string be 0, then you could use them.
You're comparing strings. JavaScript compares the ASCII code for each character of the string.
To see why you get false, look at the charCodes:
"1300".charCodeAt(0);
49
"999".charCodeAt(0);
57
The comparison is false because, when comparing the strings, the character codes for 1 is not greater than that of 9.
The fix is to treat the strings as numbers. You can use a number of methods:
parseInt(string, radix)
parseInt("1300", 10);
> 1300 - notice the lack of quotes
+"1300"
> 1300
Number("1300")
> 1300
You can "cast" to number using the Number constructor..
var number = new Number("8"); // 8 number
You can also call parseInt builtin function:
var number = parseInt("153"); // 153 number
Do this.
var x=parseInt(document.forms["frmOrder"]["txtTotal"].value);
var y=parseInt(document.forms["frmOrder"]["totalpoints"].value);