I have several numbers to proceed, let's assume that my numbers are :
14000,32100,510,2100, and 10000
So, how to make the numbers recognized as thousands or hundreds in javascript?
Is there any function for this?
Use a logarithm. A base 10 log if available, or make a base 10 log from a natural log (ln) via ln(n)/ln(10). Like so:
var log10=function(n){return Math.log(n)/Math.log(10);};
log10(100); //2
log10(10000); //4
log10(1000000);//6, uh actually 5.999999999999999
Might need to round the result due to lack of precision. Rounded version:
function log10(n){
return Math.round(100*Math.log(n)/Math.log(10))/100;
}
[10,100,1000,10000,100000,1000000].map(log10);
/*
1,2,3,4,5,6
*/
Also you should cache the Math.log(10) result if performance is an issue;
Try this one:
var number = 5300;
function NumberName(number)
{
switch (number.toString().length)
{
case 3:
return "hundreds";
case 4:
return "thousands";
}
}
int x = Math.floor(Math.log10(number)) + 1;
returns the total number of digits of a number (for 100 returns 3, for 1000 returns 4)
I don't know if there is a built-in function like that sorry, but if you just have integers you can write your own function for that:
function numberDigits(number) {
return number.toString().length
}
Now you can easily dicide if the number is thousands or hundreds etc...
Note that this only works with integer values!
I don't know how your Mark-up looks like :
But for a given markup like below:
<div class="save-sale" style="font-size: .8em; padding-top: 4em">10000</div>
You can use something like:
$(function () {
$(".save-sale").click(function (i) {
var a = $.trim($(".save-sale").text()).length;
alert(a);
});
});
FIDDLE
In JavaScript, No method exist to identify a number is hundreds or thousands, but you can create your own
ex:
function check(num){
if(num>999) { return 'thousands'; }
if(num>99) { return 'hundreds'; }
}
Related
I have two functions here...
function getCostOne() {
var cost = 1.5;
return 1 * cost.toFixed(2);
}
and...
function getCostTwo() {
var cost = 1.5;
return 1 + cost.toFixed(2);
}
What is the difference between multiplying cost.toFixed(2) and adding cost.toFixed(2)?
Why does multiplying it return .5 and adding return .50?
Those functions return 1.5 and "11.50" respectively. Working JSBin Demo...
console.log(1 * '1.50');
console.log(1 + '1.50');
It looks like the string is cast in the first case (as though you had called parseFloat('1.50') and then concatted in the second. However, this is only the results on my own browser. Take a look at the official MDN Web Docs...
console.log('foo' * 2);
// expected output: NaN
So, Chrome is probably handling it well, but I wouldn't expect that kind of behavior across all browsers!
If you want them to both definitely return the right numbers, do all the mathematical logic first, and then format it with toFixed(). That code would look like...
function getCostTwo() {
var cost = 1.5;
cost += 1; // do the math logic FIRST!
return cost.toFixed(2); // once the number is just right, we format it!
}
I have a system that reads prices without decimals.
Example: 2890 = $28.90
I also have a system that takes a websites price of a product with the result being anywhere from $40.25 to just $40 (with no decimals places). I need most likely a regex or a function using javaScript or jQuery that would convert something like $40.25 to 4025 or $40 to 4000. Because I need to send the second system's returning number to the first system which will only except numbers without decimal places.
I originally thought I had it with this: item.price = Number(item.price.replace(/[^0-9\.-]+/g,"")*100); where item.price in this case equals $79.99 but I got a result back as 7998.99999999 instead of 7999 which is what I need and I can't have those decimals places, so parseFloat isn't an option. Would appreciate the help!
Don't re-invent the wheel, use a library! Try https://www.npmjs.com/package/parse-currency
import parseCurrency from 'parse-currency'
const foo = parseCurrency('$10.50')
console.log(foo) // 10.5
const bar = parseCurrency('$1,000,000.25')
console.log(bar) // 1000000.25
As Duncan mentioned, parse-currency library would be the way, but it is not enough for your problem. Let's make a better function...
function parseCurrency(amount) {
var number = amount.replace(/[^\d|\.]/g, ''); // Removes everything that's not a digit or a dot
var parsedToFloat = parseFloat(Math.round(number * 100) / 100); // Make a float number even it is an integer
return parsedToFloat.toFixed(2); // Now make sure that it will have always 2 decimal places
}
// This will return the following results...
parseCurrency('$40'); // "40.00"
parseCurrency('$40.25'); // "40.25"
parseCurrency('$40,000.25'); // "40000.25"
As you asked for a number that won't be fixed, you can do something like that:
const currencies = [
'$40',
'$45.25',
'$45.251123456789',
'$1,000',
'$1,000.25'
];
function convertToNumber(currency) {
const number = currency.replace(/[^\d|\.]/g, '');
return parseFloat(parseFloat(number).toFixed(2)) * 100;
}
console.log(currencies.map(convertToNumber))
I have a function:
function splitToDigits(n) {
var digits = ("" + n).split("").map(function(item) {
return parseInt(item, 10);
});
console.log(digits);
}
console.log(splitToDigits(123456784987654321));
This is returning digits = [1,2,3,4,5,6,7,8,4,9,8,7,6,5,4,3,2,0].
Any idea why the last element is 0? I noticed that when I delete 2 elements from the array it acts normally. Thanks for all the great answers! :)
As Jaromanda X mentioned in the comments section above, JavaScript does not have enough precision to keep track of every digit in the integer you passed to your function.
To fix this problem, you should instead pass a string:
console.log(splitToDigits('123456784987654321'))
However, I would also like to point out that you can greatly simplify your splitToDigits method:
function splitToDigits(n) {
return [].map.call(n + '', Number)
}
console.log(splitToDigits('123456784987654321'))
console.log(splitToDigits(1234))
It's because Javascript is truncating numbers.
The best way to see this is by doing this console.log:
function splitToDigits(n) {
console.log(n);
var digits = ("" + n).split("").map(function(item) {
return parseInt(item, 10);
});
}
Then, when you ran: splitToDigits(123456784987654321), you already get 123456784987654320. Hence, it has nothing to do with your code as you have still not processed it.
If you add digits, it changes to scientific notation:
splitToDigits(1234567849876543211521521251) // turns to 1.2345678498765432e+27
It's a Javascript precision issue. That's all :)
I am creating a class to convert an integer to a sentence in a natural language. I've got some basic checks going on to ensure that the number given is between -9999 and 9999. I feel like this works for the most part.
However, once the program reaches "this.convertSentence" - past the try/catch block and error checking, I'm wondering what the best practice is now to decompose the problem into the various function calls it will need to run through to get the job done.
What I'm planning on doing with this.convertSentence is doing some checking for number size, etc...and then sending the number off to separate functions to do more work and having them propagate a sentence to return. I'm not sure if I want a variable just within my class to work with or whether I should be passing a variable around for the sentence to build. Things like this I am wondering about.
/**
* A class for converting an integer to a natrual language sentence in Spanish.
* Accepts integers from -9999 to 9999
*
*/
function NumberToWord () {
this.getSentence = function(number) {
// Check for erroneous input. Accepts only -9999 thru 9999 integers
try
{
if(number === parseInt(number) && number > -10000 && number < 10000) {
return this.convertSentence(number);
}
else {
throw new Error("Argument is not an integer between -9999 and 9999");
}
}
catch(e){
console.log(e.name + " " + e.message);
}
};
this.convertSentence = function(number) {
return "This is where I'll start the logic for the sentence";
};
}
var numberToWord = new NumberToWord();
// Tests
console.log(numberToWord.getSentence(9999));
console.log(numberToWord.getSentence(-9999));
console.log(numberToWord.getSentence(10000));
console.log(numberToWord.getSentence(-10000));
console.log(numberToWord.getSentence(0));
console.log(numberToWord.getSentence(1.1));
console.log(numberToWord.getSentence(-9999.1));
console.log(numberToWord.getSentence(10001));
console.log(numberToWord.getSentence(-10001));
console.log(numberToWord.getSentence(5.5));
console.log(numberToWord.getSentence());
There are a few things I found amiss in your code:
You don't need a class. You simply want to convert a number to a sentence. Use a function.
Why are both getSentence and convertSentence public? Only getSentence should be public.
Since your class will (in all probability) only be instatiated once, use the singleton pattern.
Things I would do:
Because you want to make your code modular, I would use the module pattern.
You can delegate specific tasks to different functions, but keep them in a private namespace.
Here's the code:
Number.prototype.toWord = function () {
return function (lang) {
var number = this.valueOf();
if (parseInt(number) === number) {
if (number < 10000 && number > 10000) {
switch (lang) {
case "es":
return toSpanish(number);
case "en":
default:
return toEnglish(number);
}
} else throw new RangeError("Expected an integer between ±10000.");
} else throw new TypeError("Expected an integer.");
};
function toSpanish(number) {
// convert the number to Spanish
}
function toEnglish(number) {
// convert the number to English
}
}();
Then you can use it like this:
var number = 1337;
alert(number.toWord("es"));
Edit: I wrote a simple function which will do what you want. However it's in English. I don't know Spanish so you'll have to implement that yourself. Here's the demo: http://jsfiddle.net/XKYhx/2/
My thinking would be to check how many parts you are going to have to the sentence and build an array to match with the substrings. for example, in English anyway (I don't speak Spanish!)
as natural language you would say (minus) xxx thousand and xxx
since your number has a max / min of ~10000 / ~-10000,
in pseudocode:
var sign = ""
var wholeparts = new Array()
var mantissaparts = new Array()
if number < 0,
sign = "minus"
number = math.abs(number) // turn the number into a positive number now we have the sign
var whole = math.floor(number) //get whole number
var mantissa = number - whole //get the after decimal part if exists
if whole > 1000
wholeparts.push(math.floor(whole/1000)) //get the thousands part
wholeparts.push(whole - parts[0]*1000) // add the hundreds
else
parts.push(whole)
if mantissa.length > 0
do something similar for the mantissa to the mantissaparts array.
At this point you would have the sentence structure broken down then:
string sentance:
foreach (var part in wholeparts)
stringify and check each number, converting to human words depending on index, ie "seven" or "seventy", add each to the string.
if wholeparts.length > 1 : sentence = sentence + " thousand and"
then if you had a mantissa, sentence = sentence + "point" .. then and the mantissa as natural language.
Best breakdown I can think of would be:
method to convert a number (whole or mantissa) to an array,
method to convert the array to natural language, with a parameter saying if it is whole or mantissa for the different wording that would be used.
method that accepts a number in string form and returns the natural language equivalent
Hope that helps .. was thinking on the fly.
While playing around with random numbers in JavaScript I discovered a surprising bug, presumably in the V8 JavaScript engine in Google Chrome. Consider:
// Generate a random number [1,5].
var rand5 = function() {
return parseInt(Math.random() * 5) + 1;
};
// Return a sample distribution over MAX times.
var testRand5 = function(dist, max) {
if (!dist) { dist = {}; }
if (!max) { max = 5000000; }
for (var i=0; i<max; i++) {
var r = rand5();
dist[r] = (dist[r] || 0) + 1;
}
return dist;
};
Now when I run testRand5() I get the following results (of course, differing slightly with each run, you might need to set "max" to a higher value to reveal the bug):
var d = testRand5();
d = {
1: 1002797,
2: 998803,
3: 999541,
4: 1000851,
5: 998007,
10: 1 // XXX: Math.random() returned 4.5?!
}
Interestingly, I see comparable results in node.js, leading me to believe it's not specific to Chrome. Sometimes there are different or multiple mystery values (7, 9, etc).
Can anyone explain why I might be getting the results I see? I'm guessing it has something to do with using parseInt (instead of Math.floor()) but I'm still not sure why it could happen.
The edge case occurs when you happen to generate a very small number, expressed with an exponent, like this for example 9.546056389808655e-8.
Combined with parseInt, which interprets the argument as a string, hell breaks loose. And as suggested before me, it can be solved using Math.floor.
Try it yourself with this piece of code:
var test = 9.546056389808655e-8;
console.log(test); // prints 9.546056389808655e-8
console.log(parseInt(test)); // prints 9 - oh noes!
console.log(Math.floor(test)) // prints 0 - this is better
Of course, it's a parseInt() gotcha. It converts its argument to a string first, and that can force scientific notation which will cause parseInt to do something like this:
var x = 0.000000004;
(x).toString(); // => "4e-9"
parseInt(x); // => 4
Silly me...
I would suggest changing your random number function to this:
var rand5 = function() {
return(Math.floor(Math.random() * 5) + 1);
};
This will reliably generate an integer value between 1 and 5 inclusive.
You can see your test function in action here: http://jsfiddle.net/jfriend00/FCzjF/.
In this case, parseInt isn't the best choice because it's going to convert your float to a string which can be a number of different formats (including scientific notation) and then try to parse an integer out of it. Much better to just operate on the float directly with Math.floor().