How do I reliably find fractions and decimals in javascript - javascript

Q) I want to be able to parse a string in js and output the parts of the string that are either a number or a fraction.
e.g: "1.5 litres 1/4 cup"
Note: I've already figured out how to get the whole numbers and decimals from the example string below, but not the fraction representations.
I'm currently using something like this:
const originalString = "1.5 litres 1/4 cup";
var number_regex = /[+-]?\d+(\.\d+)?/g;
var matches = [];
var match;
// FIX - does this ever actually get stuck ?
// replace this with non-while loop from article: http://danburzo.ro/string-extract/
while ((match = number_regex.exec(originalString)) !== null) {
matches.push({
original: match[0],
newVal: ''
});
}
console.log(matches)

You could use this to extract each number as an array of strings
const input = `Take 1.5 litres 1/4 cup of sugar
and 2ml or 2/3 teaspoon or salt
then take 5 litres of 2.5% vinegar`
const regex = /[+-]?\d+(?:[\.\/]?\d+)?/gm
console.log(
[...input.matchAll(regex)].map(a => a[0])
)
// returns ["1.5", "1/4", "2", "2/3", "5", "2.5"]

Related

Can you tell me why my code for turning an array to a number, adding one, and returning an array only works on some datasets?

I'm trying to solve the following Leetcode problem:
You are given a large integer represented as an integer array digits,
where each digits[i] is the ith digit of the integer. The digits are
ordered from most significant to least significant in left-to-right
order. The large integer does not contain any leading 0's.
Increment the large integer by one and return the resulting array of
digits.
Example 1:
Input: digits = [1,2,3] Output: [1,2,4] Explanation: The array
represents the integer 123. Incrementing by one gives 123 + 1 = 124. Thus, the result should be [1,2,4].
Here's my code :
var plusOne = function(digits) {
let newDigit = digits.join('')
if (newDigit.length > 15) {
let digitLength = newDigit.length
let secondHalf = newDigit.slice(digitLength - 15, digitLength)
secondHalf = parseInt(secondHalf) + 1
secondHalf = Array.from(String(secondHalf), Number)
digits.splice(digitLength - 15, 15)
return digits.concat(secondHalf)
}
let Digit = parseInt(newDigit) + 1
const answer = Array.from(String(Digit), Number)
return answer
};
Works for many data sets. Get's the following error on the following set. Why :(
When you do parseInt(secondHalf), you're effectively dropping any leading zeros in that string, and as a result those zeros don't get included in the final array. The input digits are guaranteed not to have any leading zeros, but that doesn't mean that there won't be any leading zeros if you slice the string in the middle.
Also, even fixing that, what about input arrays that are longer than 30 characters?
Consider using a BigInt instead, it'll be a lot easier.
const plusOne = function(digits) {
const bigInt = BigInt(digits.join('')) + 1n;
return [...String(bigInt)].map(Number);
}
console.log(plusOne(
'590840235570031372488506112'.split('').map(Number)
));

Format number to last two decimals

I am trying to format numbers in JS to last two decimal.
For example 10100 becomes 101.00 - 606000 becomes 6,060.00 - 7600 becomes 76.00 and so on.
I have tried num.toFixed(2) but that was not of help. I also tried Number(10100).toLocaleString("es-ES", {minimumFractionDigits: 0}) but I end up with 10.100 so it seems off by one decimal.
So
num.toFixed(2)
What its doing its formatting,
Which would be 10.123 -> 10.12
what you should do is divide number by 100.
var number = 10100
number = number / 100
would be what you need.
I will approach this problem by using the help of strings.
Strings can be easily manipulated based on our requirements and then can be converted back to numbers. So, the solution goes like this
Convert the number to string
Manipulate the string to add a decimal before last two character
Convert the string back to number
const formatNumberToLastTwoDecimal = (number) => {
// Convert the number to String
const inputNumAsStr = number.toString();
// Manipulate the string and add decimal before two char
const updatedStr = `${inputNumAsStr.slice(0, -2)}.${inputNumAsStr.slice(-2)}`;
// Return by converting the string to number again
// Fix by 2 to stop parseFloat() from stripping zeroes to right of decimal
return new Number(parseFloat(updatedStr)).toFixed(2);
}
console.log(formatNumberToLastTwoDecimal(606000));
The most simplified way:
output = (number/100).toFixed(2)
And the complex way:
var c = 7383884
a = c.toString()
var output = parseFloat([a.slice(0, -2), ".",a.slice(-2)].join(''))
document.write(output)

In Javascript numbers with only double zeros in their decimal place lost their double zero when converted to String ? Why?

I am developing a web app in which I need to concat some numbers as String format
One of the number need 00 at decimal place if it is whole number (ex 15.00)
But when I concat it with other number , the 00 got lost (ex 15.00 => 15)
An example :
const price = 15.00;
const period = 3;
const CC = 840;
const concated = `${price}${period}${CC}`;
console.log(concated);
const saltedHash = crypto.createHash('md5').update(`${concated}GhVT+6FySEgWVeUWCHLo2lks`).digest('hex');
post[0].saltedHash = saltedHash;
post[0].string = `${concated}GhVT+6FySEgWVeUWCHLo2lks`;
Now the problem is , the constant concated contains 153840 instead of 15.003840
Why this problem occurring ?
How to preserve 00s?
You can achieve that by using toFixed(), something like:
const concated = `${price.toFixed(2)}${period}${CC}`;
const price = 15.00;
const period = 3;
const CC = 840;
const concated = `${price.toFixed(2)}${period}${CC}`;
console.log(concated);
The issue is that when you use a template literal it converts the number to string, i.e. String(15) === "15", whereas when you do 15..toFixed(2) it "returns a string representing a number in fixed-point notation".
Thus, 15..toFixed(2) === "15.00", i.e. typeof 15.00.toFixed(2) === "string"

Significant Figures in JavaScript

I have a few scientists for clients and they have some problems with how toPrecision is rounding in JavaScript. They want everything rounded to a MAX of 3 sig figs which works most of the time but let me give a few examples of what they want:
Lab value to rounded value
123.5 to 124
1234 to 1230
12.0 to 12.0
0.003 to 0.003
So in other words round things with more than 3 sig figs down to 3. If something has 1 or 2 sig figs DONT append a zero (as that implies the lab was more accurate then they really were) but also in the case of 12.0 DONT remove the zero (as that implies the lab is less accurate then they really were)
Using toPrecision works for all examples given except for the 12.0 to 12.0 example:
var nums = [123.5, 1234, 12.0, 0.003]
var out = nums.map(num => parseFloat(num.toPrecision(3)))
// => [124, 1230, 12, 0.003]
It rounds numbers with more than 3 sig figs to 3, but if you use a number with a .0 or .00 on the end it fails. The reason for this is that the JavaScript engine equates 1.00 to 1, and 12.0 to 12, so the problem is actually not toPrecision, but rather JavaScript itself.
To work around this, what you can do is input numbers as strings, and use toPrecision if there isn't a decimal zero, otherwise operate on the string itself:
var nums = ['123.5', '1234', '12.0', '0.003', '1.000', '1236.00'];
var out = nums.map(str => {
if (/\.0+$/.test(str)) { // test if it ends with .0 or .00, etc.
// use alternative string method:
var zeros = str.match(/[0]+$/)[0].length; // count the no. of trailing zeros
var sigfigs = parseFloat(str).toString().length; // no. of other sig figs
var zerosNeeded = 3 - sigfigs;
if (zerosNeeded < 0) {
return parseFloat(parseFloat(str).toPrecision(3)).toFixed();
} else {
return str.substring(0, sigfigs + 1 + zerosNeeded); // +1 for the decimal point
}
} else {console.log(str)
return parseFloat(parseFloat(str).toPrecision(3)).toString()
}
});
// => ["124", "1230", "12.0", "0.003", "1.00", "1240"]
This works, however as the result must be in a string format if you need to work with floating point numbers and similar, I'd recommend using a different language such as Python. Anyway, I hope this helps!
All you need to do is to write a custom parser.
See this example:
const data = [123.5, 1234, 12.0, 0.003, 100.0, 1.0];
data.forEach(n => {
const result = customToPrecision(n, 3);
console.log(`${n} -> ${result}`);
});
function customToPrecision(number, precision){
let result = number.toPrecision(precision);
// Check if original number is a float
if (number % 1 !== 0){
result = result
.replace(/0+$/, '') // Remove trailing zeros
.replace(/\.$/, '.0'); // Add one zero to incomplete decimal
}
return result;
}

How to get a double random number and put its digits to variables?

I want to get a random double number (for example 4.58)
and put its digits to three variables - 4 to the first variable, 5 to the second variable and 8 to the third variable.
Not sure why you need this to be a floating-point number. Just create a three-digit number, convert it to a string, and split it into an array.
var numArr = (Math.floor(Math.random() * 900) + 100).toString().split('');
You can get at the numbers using the normal array method: numArr[0] etc.
To convert it to number, add a period in the first array position and then join it back to together:
numArr.splice(1, 0, '.');
var number = numArr.join('');
DEMO
Alternatively, see this SO question on how to create random floating-point numbers.
You could do something like this:
var number = 4.26; // Your generated double number
output = []; // Array to store each digit
sNumber = number.toString(); // Convert the double to a string so we can split it
for (var i = 0, len = sNumber.length; i < len; i += 1)
{
output.push(+sNumber.charAt(i));
}
console.log(output);
The output will be:
4, 2, 6
All numbers in JavaScript are doubles: that is, they are stored as 64-bit IEEE-754 doubles.
That is, the goal is not to get a "double": the goal is to get the string reprsentation of a number formatted as "YYY.XX". For that, consider Number.toFixed, for instance:
(100).toFixed(2)
The result is the string (not a "double"!) "100.00". The parenthesis are required to avoid a grammar ambiguity in this case (it could also have been written as 100.0.toFixed or 100..toFixed), but would not be required if 100 was in a variable.
Use this. I use .replace(/[.]/g,"") for removing ".".
http://jsfiddle.net/sherali/coyv3erf/2/
var randomNumber = Math.floor(Math.random() * 900) + 100;
numArr= randomNumber.toString().replace(/[.]/g,"").split("")
var number = numArr.join("");
console.log(numArr, number); // ["8", "4", "5"] 845

Categories