How to Extract Numbers From a Polynomial String (including the + and - signs) - javascript

I'm trying to figure out how to extract e.g. -13, as a negative value out of a polynomial, e.g. -13x^2+2-12x^4. So far, I've successfully take out the powers. Additionally, my solution came up to this:
/\(+)(-)\d{1,4}/g
I know it's wrong syntax, but I'm not sure how to represent the + or - which goes with the following number.
It would be good if you can show me how to count the next x like the end of an common/searched phrase, I'm not sure about the term. You know, if it is -3x^ and the point is to extract -3, then it should be like /\ + or - \/d{1,4} x_here/g

var formula = '-13x^2+2-12x^4';
formula.match(/[+-]?\d{1,4}/g);
Returns:
["-13", "2", "+2", "-12", "4"]
If you wish to organize the numbers into coefficients and powers, here's an approach that works:
var formula = '-13x^2+2-12x^4';
function processMatch(matched){
var arr = [];
matched.forEach(function(match){
var vals = match.split('^');
arr.push({
coeff: parseInt(vals[0]),
power: vals[1] != null ? parseInt(vals[1]) : 0
})
})
console.log(arr);
}
processMatch(formula.match(/[+-]?\d+x\^\d+|[+-\s]\d[+-\s]/g))
/* console output:
var arr = [
{ coeff: -13, power: 2 },
{ coeff: 2, power: 0 },
{ coeff: -12, power: 4 }
];*/

I think you want:
var str = '2x^2-14x+5';
var re = /([+-]?\d{1,4})/g;
var result = str.match(re);

Related

Can JSON strings be converted to fractions for equations when building REST API in Node JS?

I am creating an API for a picture framing calculator. I am using Node JS with Express. The code that I'm using is this:
app.post("/api/calculator/singlematapi", (req,res) => {
let FrameWidth = req.body.FrameWidth;
let FrameWidthFraction = req.body.FrameWidthFraction
let FrameHeight = req.body.FrameHeight;
let FrameHeightFraction = req.body.FrameHeightFraction;
let PictureWidth = req.body.PictureWidth;
let PictureWidthFraction = req.body.PictureWidthFraction;
let PictureHeight = req.body.PictureHeight;
let PictureHeightFraction = req.body.PictureHeightFraction;
let MatOverlap = req.body.MatOverlap;
let MatOverlapFraction = req.body.MatOverlapFraction
let width = (1/2)*((FrameHeight+FrameHeightFraction)-(PictureHeight+PictureHeightFraction)+(MatOverlap+MatOverlapFraction));
let height = (1/2)*((FrameWidth+FrameWidthFraction)-(PictureWidth+PictureWidthFraction)+(MatOverlap+MatOverlapFraction));
res.send(`Width Cut = ${new Fraction(width).toString()}", Height Cut = ${new Fraction(height).toString()}"`);
});
Therefore, a JSON POST request would be:
{
"FrameWidth": 16,
"FrameWidthFraction": 0,
"FrameHeight": 20,
"FrameHeightFraction": 0,
"PictureWidth": 11,
"PictureWidthFraction": 0,
"PictureHeight": 17,
"PictureHeightFraction": 0,
"MatOverlap": 0.5
}
What I am trying to accomplish is that instead of a decimal - a fraction such as 1/2 can be inputted instead. For example:
{
"FrameWidth": 16,
"FrameWidthFraction": 0,
"FrameHeight": 20,
"FrameHeightFraction": 0,
"PictureWidth": 11,
"PictureWidthFraction": 0,
"PictureHeight": 17,
"PictureHeightFraction": 0,
"MatOverlap": 1/2
}
The problem I'm running into is that although I am able to convert the output from decimal to fraction using a library and this piece of code:
res.send(`Width Cut = ${new Fraction(width).toString()}", Height Cut = ${new Fraction(height).toString()}"`);
...I am not able to use a fraction as an input instead of a decimal.
Unless I'm misunderstanding - it states here: JSON data types - that Fractions pertaining to Numbers can only be displayed in decimal type formatting such as 0.5 like I have above under MatOverlap.
However, according to the same page it states that a forward slash can be used in a string.
Can I use the forward slash as the solidus to indicate a fraction when JSON data is inputted?
When I attempted to use a string by changing the above to:
{
"MatOverlap": "1/2"
}
...then it throws NaN error.
EDIT 8/1/2022
This is for further clarification regarding one of the solutions to this question: this solution found below by some random nerd.
Particularly this comment:
You can enter just a 0 with this method as well
I wrote a piece of code to serve as an example of what I mean:
app.post("/add", (req, res)=>{
let n1 = req.body.n1;
let n2 = req.body.n2.split("/").reduce((a, b) => a / b);
let sum = n1 + n2;
res.send(`Sum = ${sum}`);
});
If I input:
{
"n1": 1,
"n2": "0/1"
}
The response is: Sum = 1
{
"n1": 1,
"n2": "0"
}
The response is: Sum = 10
See how 0 needs to be written as 0/1 in order for the math to work correctly? When the input is 0 I'm looking to write just a 0.
you can convert the fraction input to decimal.
let MatOverlap = req.body.MatOverlap.split("/").reduce((a, b) => a / b)
To also accept mixed fractions:
let MatOverlap =
req.body.MatOverlap.split("/").reduce(
(a, denom) =>
a.split(" ").reduce((int, numer) => +numer + int * denom) / denom
);
You can convert string expression to number using eval. Yes yes. But first sanitize it because it's a dangerous command to run on input.
var req = {
body: {
MatOverlap: "1/2"
}
}
let expr = req.body.MatOverlap;
expr = expr.replace(/[^0-9//]/g, "");
let MatOverlap = eval(expr);
console.log(MatOverlap * 6)

converting a string with commas to a array with commas (or even just a number with commas

I'm using JS inside MaxMSP
I would like to take a string output (of separated by comma single fibonacci numbers) and convert it to either an array or number, keeping the space and commas but getting ride of the "double quotes"
I've tried a bunch of stuff here but unfortunately I'm still banging my head against the wall.
autowatch = 1;
inlets = 2;
outlets = 2;
function msg_int(num){
var a = 1;
var b = 0, temp;
while (num >= 0){
temp = a;
a = a + b;
b = temp;
num--;
outlet(0, b);
var n = temp;
digits = n.toString().replace(/(\d{1})/g,'$1, ')
outlet(1, digits);
}
return b;
}
The Input number is 14
The first outlet(0) number is 610
The second outlet(1) is "6, 1, 0, "
I would like the second outlet to be 6, 1, 0,
var result = '"6, 1, 0,"'.replace(/['"]+/g, '')
console.info(result);
It looks like you want outlet(1) to output a Max “list” as opposed to a symbol. outlet will handle that for you, but you need to hand it an array to achieve this. Here’s what it says in the docs:
If the argument to outlet is an array, it is unrolled (to one level only) and passed as a Max message or list (depending on whether the first element of the array is a number or string).
Knowing this, you need to convert digits into an array before passing it to outlet:
var n = temp;
var digits = n.toString(); // convert 610 to "610" (for example)
digits.split(""); // split "610" into ["6", "1", "0"]
outlet(1, digits);
Whether this a Max list or message depends on the type of the first element, so if you need a list of numbers (integers in your case), you could do something like this before passing it to outlet:
// map ["6", "1", "0"] to [6, 1, 0]
digits = digits.map(function (i) { return parseInt(i) });

How can I add some number to string in javascript or jquery

I have a problem. Script parsing csv to html. But number is read as a string. How can I add "0" to numbers that do not have to decimals. For example:
15,45
12,00
14,2
14,54
I want to add 0 to all numbers like 4,2
15,45
12,00
14,20
14,54
Try
var output = "15,2".split(",").map(function(val){ return val > 100 ? val: (val+"00").slice(0,2);}).join(",");
alert(output);
var output = "15,100".split(",").map(function(val){ return val > 99 ? val: (val+"00").slice(0,2);}).join(",");
alert(output);
var output = "15,".split(",").map(function(val){ return val > 100 ? val: (val+"00").slice(0,2);}).join(",");
alert(output);
In vanillaJS
var num = "14,2";
/* string to number conversion */
num = +(num.replace(',','.'));
/* set 2 digits after decimal point */
num = num.toFixed(2);
/*
Input Output
--------------
14,25 14.25
14,2 14.20
14 14.00 */
Reduced in a single statement, as suggested in the comments below:
(+num.replace(',','.')).toFixed(2);
if you have an array of strings you could easily convert them using Array.map()
var nums = ["14", "14,2", "14,25"];
nums = nums.map(n => (+n.replace(',','.')).toFixed(2));
// => ["14.00", "14.20", "14.25"]
If you get all strings as posted format in the OP you could use length :
["15,45","12,00","14,2"].forEach(function(v){
alert(v.split(',')[1].length==1?v+"0":v);
})
You can use this:
var arr = ["15,45","12,00","14,2","14,54"];
var newarr = arr.map(function(o){
var val = o.split(',');
return val[1].length == 1 ? val.join(',')+"0" : val.join(',');
});
document.querySelector('pre').innerHTML = JSON.stringify(newarr, 0, 4);
<pre></pre>

What is the faster way to convert an object with property value: "HH:MM:SS" to string "N Minutes"?

I have hundred of objects with structure like
{
movieName: 'xyz',
time: '02:15:50'
timeAsText: null
}
I need to set timeAsText with a text as "136 minutes" based on property 'time'.
Seconds should be rounded up.
Could you point me out what could be the faster approach?
I tried this with two methods (DEMO); the first using map, and the second using a plain for...loop. As you can see from the demo the plain loop is considerably faster:
var out = [];
for (var i = 0, l = arr.length; i < l; i++) {
var obj = arr[i];
var time = obj.time.split(':').map(Number);
if (time[2] > 0) { time[1]++; }
obj.timeAsText = (time[0] * 60) + time[1] + ' minutes';
out.push(obj);
}
the best to do is probably that, and, seeing the numbers of similar answers, probably the only one.
-first, you use split(':') to make your string become a array of parseable string;
-then, parse the value to int. Use parseInt
at this time, you should have a array like that
[number_of_hours, number_of_minutes,number_of_second]
-then you just have to add the different values like
obj.timeAsText = array[0]*60+array[1]+Math.round(array[2]/60)+' minutes';
The full answer :
var arr=obj.time.split(':').forEach(function(entry){
entry=parseInt(entry);
});
obj.timeAsText= arr[0]*60+arr[1]+Math.round(array[2]/60)+" minutes";
Try this
var obj = {
movieName: 'xyz',
time: '02:15:50'
timeAsText: null
}
var a = obj.time.split(':'); // split it at the colons
var minutes = parseInt(+a[0]) * 60 + parseInt(+a[1]) + Math.round(parseInt(+a[2])/60);
obj.timeAsText = minutes + " minutes";
I don't know if it's the fastest, but it's the most easily readable one:
var test = {
movieName: 'xyz',
time: '02:15:50',
timeAsText: null
};
test.time.replace(/^(\d{2}):(\d{2}):(\d{2})$/, function(m, p1, p2, p3) {
// Multiplication and division implicitly converts p1 and p3 to numbers
return p1*60 + parseInt(p2) + Math.ceil(p3/60);
});

How can I find the length of a number?

I'm looking to get the length of a number in JavaScript or jQuery?
I've tried value.length without any success, do I need to convert this to a string first?
var x = 1234567;
x.toString().length;
This process will also work forFloat Number and for Exponential number also.
Ok, so many answers, but this is a pure math one, just for the fun or for remembering that Math is Important:
var len = Math.ceil(Math.log(num + 1) / Math.LN10);
This actually gives the "length" of the number even if it's in exponential form. num is supposed to be a non negative integer here: if it's negative, take its absolute value and adjust the sign afterwards.
Update for ES2015
Now that Math.log10 is a thing, you can simply write
const len = Math.ceil(Math.log10(num + 1));
Could also use a template string:
const num = 123456
`${num}`.length // 6
You have to make the number to string in order to take length
var num = 123;
alert((num + "").length);
or
alert(num.toString().length);
I've been using this functionality in node.js, this is my fastest implementation so far:
var nLength = function(n) {
return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1; 
}
It should handle positive and negative integers (also in exponential form) and should return the length of integer part in floats.
The following reference should provide some insight into the method:
Weisstein, Eric W. "Number Length." From MathWorld--A Wolfram Web Resource.
I believe that some bitwise operation can replace the Math.abs, but jsperf shows that Math.abs works just fine in the majority of js engines.
Update: As noted in the comments, this solution has some issues :(
Update2 (workaround) : I believe that at some point precision issues kick in and the Math.log(...)*0.434... just behaves unexpectedly. However, if Internet Explorer or Mobile devices are not your cup of tea, you can replace this operation with the Math.log10 function. In Node.js I wrote a quick basic test with the function nLength = (n) => 1 + Math.log10(Math.abs(n) + 1) | 0; and with Math.log10 it worked as expected. Please note that Math.log10 is not universally supported.
There are three way to do it.
var num = 123;
alert(num.toString().length);
better performance one (best performance in ie11)
var num = 123;
alert((num + '').length);
Math (best performance in Chrome, firefox but slowest in ie11)
var num = 123
alert(Math.floor( Math.log(num) / Math.LN10 ) + 1)
there is a jspref here
http://jsperf.com/fastest-way-to-get-the-first-in-a-number/2
You should go for the simplest one (stringLength), readability always beats speed. But if you care about speed here are some below.
Three different methods all with varying speed.
// 34ms
let weissteinLength = function(n) {
return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1;
}
// 350ms
let stringLength = function(n) {
return n.toString().length;
}
// 58ms
let mathLength = function(n) {
return Math.ceil(Math.log(n + 1) / Math.LN10);
}
// Simple tests below if you care about performance.
let iterations = 1000000;
let maxSize = 10000;
// ------ Weisstein length.
console.log("Starting weissteinLength length.");
let startTime = Date.now();
for (let index = 0; index < iterations; index++) {
weissteinLength(Math.random() * maxSize);
}
console.log("Ended weissteinLength length. Took : " + (Date.now() - startTime ) + "ms");
// ------- String length slowest.
console.log("Starting string length.");
startTime = Date.now();
for (let index = 0; index < iterations; index++) {
stringLength(Math.random() * maxSize);
}
console.log("Ended string length. Took : " + (Date.now() - startTime ) + "ms");
// ------- Math length.
console.log("Starting math length.");
startTime = Date.now();
for (let index = 0; index < iterations; index++) {
mathLength(Math.random() * maxSize);
}
First convert it to a string:
var mynumber = 123;
alert((""+mynumber).length);
Adding an empty string to it will implicitly cause mynumber to turn into a string.
Well without converting the integer to a string you could make a funky loop:
var number = 20000;
var length = 0;
for(i = number; i > 1; ++i){
++length;
i = Math.floor(i/10);
}
alert(length);​
Demo: http://jsfiddle.net/maniator/G8tQE/
I got asked a similar question in a test.
Find a number's length without converting to string
const numbers = [1, 10, 100, 12, 123, -1, -10, -100, -12, -123, 0, -0]
const numberLength = number => {
let length = 0
let n = Math.abs(number)
do {
n /= 10
length++
} while (n >= 1)
return length
}
console.log(numbers.map(numberLength)) // [ 1, 2, 3, 2, 3, 1, 2, 3, 2, 3, 1, 1 ]
Negative numbers were added to complicate it a little more, hence the Math.abs().
I'm perplex about converting into a string the given number because such an algorithm won't be robust and will be prone to errors: it will show all its limitations especially in case it has to evaluate very long numbers. In fact before converting the long number into a string it will "collapse" into its exponential notation equivalent (example: 1.2345e4). This notation will be converted into a string and this resulting string will be evaluated for returning its length. All of this will give a wrong result. So I suggest not to use that approach.
Have a look at the following code and run the code snippet to compare the different behaviors:
let num = 116234567891011121415113441236542134465236441625344625344625623456723423523429798771121411511034412365421344652364416253446253446254461253446221314623879235441623683749283441136232514654296853446323214617456789101112141511344122354416236837492834411362325146542968534463232146172368374928344113623251465429685;
let lenFromMath;
let lenFromString;
// The suggested way:
lenFromMath = Math.ceil(Math.log10(num + 1)); // this works in fact returns 309
// The discouraged way:
lenFromString = String(num).split("").length; // this doesn't work in fact returns 23
/*It is also possible to modify the prototype of the primitive "Number" (but some programmer might suggest this is not a good practice). But this is will also work:*/
Number.prototype.lenght = () => {return Math.ceil(Math.log10(num + 1));}
lenFromPrototype = num.lenght();
console.log({lenFromMath, lenFromPrototype, lenFromString});
A way for integers or for length of the integer part without banal converting to string:
var num = 9999999999; // your number
if (num < 0) num = -num; // this string for negative numbers
var length = 1;
while (num >= 10) {
num /= 10;
length++;
}
alert(length);
I would like to correct the #Neal answer which was pretty good for integers, but the number 1 would return a length of 0 in the previous case.
function Longueur(numberlen)
{
var length = 0, i; //define `i` with `var` as not to clutter the global scope
numberlen = parseInt(numberlen);
for(i = numberlen; i >= 1; i)
{
++length;
i = Math.floor(i/10);
}
return length;
}
To get the number of relevant digits (if the leading decimal part is 0 then the whole part has a length of 0) of any number separated by whole part and decimal part I use:
function getNumberLength(x) {
let numberText = x.toString();
let exp = 0;
if (numberText.includes('e')) {
const [coefficient, base] = numberText.split('e');
exp = parseInt(base, 10);
numberText = coefficient;
}
const [whole, decimal] = numberText.split('.');
const wholeLength = whole === '0' ? 0 : whole.length;
const decimalLength = decimal ? decimal.length : 0;
return {
whole: wholeLength > -exp ? wholeLength + exp : 0,
decimal: decimalLength > exp ? decimalLength - exp : 0,
};
}
var x = 1234567;
String(x).length;
It is shorter than with .toString() (which in the accepted answer).
Try this:
$("#element").text().length;
Example of it in use
Yes you need to convert to string in order to find the length.For example
var x=100;// type of x is number
var x=100+"";// now the type of x is string
document.write(x.length);//which would output 3.

Categories

Resources