refactor this basic code that determines if number is in tens, hundreds, thousands etc
if (n<100) {
x = 10;
} else if (n<1000) {
x = 100;
} else if (n<100开发者_StackOverflow社区00) {
x = 1000;
} else if (n....
etc. etc.
Is there a nice concise, scalable method for this type of problem? My brain has decided to stop working.
var x = Math.pow( 10, Math.floor( Math.log(n) / Math.log(10) ) );
This one might be preferable, because it's available as a constant so it doesn't need to be calculated each time:
var x = Math.pow( 10, Math.floor( Math.log(n) / Math.LN10 ) );
It basically comes down to rounding down logarithmically.
Edit: Because a combination of log
and /
often tends to result in errors, it might be a good idea to round the quotient as well (currently, Math.log(1000) / Math.LN10 === 2.9999999999999996
).
var x = Math.pow( 10, Math.floor( Math.round( Math.log(1000) / Math.LN10 * 1e10 ) / 1e10 ) );
This rounding might result in new errors, but for 'normal' inputs the answer is now more often correct.
Here's a solution using recursion:
function find_place( x, n ) {
return x >= 10 ? find_place( x/10, ++n || 1 ) : Math.pow( 10, n || 0 );
}
find_place( 3 ); // 1
find_place( 33 ); // 10
find_place( 333 ); // 100
EDIT: Fixed to use x >= 10
instead of x > 10
.
Here's a version that removes the need for Math.pow()
.
function find_place(x, n) {
return x >= 10 ? find_place(x / 10, (n || 1) * 10) : n || 1;
}
Or run effectively the same code in a loop instead of a recursive function to speed it up a bit.
var x = 12345,
n = 1; // n will hold the result
while (x >= 10) {
x /= 10;
n *= 10;
}
One cleanup is to make this its own method, with return values. That way you avoid all the else if
's
...
if (n < 100) return 10;
if (n < 1000) return 100;
if (n < 10000) return 1000;
...
This isn't as good, as general, as clean as using the pow() function @pimvdb suggested, but it is a good more general way to clean up code with an "else-iffy" feel like the one presented.
You could try
x=Math.pow(10, Math.floor(Math.log(n)/Math.LN10));
I needed to do something similar and came up with the following:
x = Math.pow( 10, ( '' + n ).length - 1 );
And some test cases, jsFiddle:
n = 33; // x = 10
n = 213; // x = 100
n = 1776; // x = 1000
Don't know if the performance is any better than all the log
stuff, and this assumes n
is an integer.
精彩评论