In my nodeJs code I make a REST call to a 3rd party api and one of the values in the response is a string value e.g:
"total": "-15"
Note that this value can either be a negative number, zero or a positive number, but as a string.
e.g:
"total": "-5"
"total": "0"
"total": "+3"
How can I convert this value to be as follows? Based off the above example:
5 under
level par
3 over
I am quite new to node/javascript - is regex the best option to do this?
As Blunt Jackson said, regex will probably be slower. Here is a conversion function example:
const toText = (value) => {
const parsed = parseInt(value)
return parsed > 0 ? `${parsed} over` : parsed < 0 ? `${Math.abs(parsed)} under` : 'level par';
}
console.log(toText("-5"));
console.log(toText("0"));
console.log(toText("+3"));
I like this question because I like Code Golf :D
So my suggestion would be this one-liner:
const toText = v => v == 0 ? "level par" : v < 0 ? `${-v} under` : `${+v} over`;
console.log(toText("-5"));
console.log(toText("0"));
console.log(toText("+3"));
Works with Numbers or Strings as parameter.
Related
Is there a way to parse math equations as input using JavaScript?
for example, when a user enters "10-25" as input, it is parsed to -15
I tried using eval, which works, but it allows users to run all JavaScript code, not just math equations.
If it's possible, I'd like to also allow some functions, like sin(), cos(), and degreesToRadians(), but not all functions.
examples
"5" //returns 5
"12-20" //returns -8
"3/2" //returns 1.5
"sin(3.14)" //returns 0.00159265292
"sin(degreesToRadians(180/2)) * 10" //returns 10
"alert('hi')" //doesn't work
You can split expression by math operations and check them.
Next code does it for: ( ) / *
mathExpression.replace(/([()/*])/g, " $1 ").split(" ").filter(v => v);
var allowedCommands = ["(", ")", /^\d*\.?\d*e?$/, "*", "/", "+", "-", "sin", "cos", "degreesToRadians"];
function checkCommand(arg) {
return allowedCommands.some(v => {
if (v instanceof RegExp) {
return v.test(arg)
} else {
return v == arg;
}
});
}
function checkAllowedCommands(mathExpression) {
var commands = mathExpression.replace(/([()/*+-])/g, " $1 ").split(" ").filter(v => v);
var filterNotAllowedCommands = commands.filter(v => !checkCommand(v));
return filterNotAllowedCommands.length == 0;
}
console.log(checkCommand("degreesToRadians"));
console.log(checkCommand("234"));
console.info("right expression");
console.info(checkAllowedCommands("sin(degreesToRadians(180/2)) * 10"));
console.info(checkAllowedCommands("(1.2e-6)"))
console.info(checkAllowedCommands("sin(1+2)"));
console.warn("wong expression");
console.info(checkAllowedCommands("alert('hi')"));
Perhaps something like this package: https://www.npmjs.com/package/nerdamer
I've used Nerdamer in a few projects in the past, and it's pretty solid. Short of that, there's no "simple" way to do it short of implementing your own mini-parser that I know of.
In the same way we have the hex "number" using the characters 123456789abcdef, and you can simply do integer.toString(16) to go from integer to hex:
> (16).toString(16)
'10'
... I would like to instead use a custom character set, and a custom base. So for hex say I wanted to use the characters 13579acegikmoqsu, then it would be something like this:
> (16).toString(16, '13579acegikmoqsu')
'ik'
I don't actually know what the output value would be in this case, just made that up. But I am looking for how to do this in JavaScript.
Another example outside of hex would be a, for example, base 6 number converted to a string using the character set and123, so it would be something like this:
> (16).toString(6, 'and123')
'a3d'
I don't know what the value is in this case here either, I don't know how to calculate it. Basically wondering how to do this in JavaScript, not necessarily using this toString api, preferably it would be a bit more low-level so I could also understand the logic behind it.
Likewise, it would be helpful to know how to reverse it, so to go from a3d => 16 as in this pseudo-example.
You could map the character values of the integer value as index
function toString(n, characters) {
var radix = characters.length;
return Array
.from(n.toString(radix), v => characters[parseInt(v, radix)])
.join('');
}
console.log(toString(16, '13579acegikmoqsu')); // 31
A version without toString and parseInt.
function toString(n, characters) {
var radix = characters.length,
temp = [];
do {
temp.unshift(n % radix);
n = Math.floor(n / radix);
} while (n)
return temp
.map(i => characters[i])
.join('');
}
console.log(toString(16, '13579acegikmoqsu')); // 31
how would I sort this using .sort() function in javascript? I know I can add a comparison function here but I'm not sure how I would program this.
Before
1 024c
100 000c
143c
1 020c
10 000c
After
143c
1 020c
1 024c
10 000c
100 000c
If your input is an array then you can use a comparator function
(a,b) => a.replace(/[^\d.]/g, "") - b.replace(/[^\d.]/g, "")
this will remove c and space from the string to form number and compare. See the code below.
var data = ["1 024c",
"100 000c",
"143c",
"1 020c",
"10 000c"]
var sorted = data.sort( (a,b) => a.replace(/[^\d.]/g, "") - b.replace(/[^\d.]/g, ""));
console.log(sorted);
It seems like you want to sort it based on the numbers in them, while excluding spaces.
x.sort(
(eachObj, prevObj) =>
parseInt(eachObj.replace(" ","")) - parseInt(prevObj.replace(" ",""))
);
In ES6
I have an array of number suffixes in order of how big they are:
[0] = 0 - 999 ("")
[1] = 1,000 - 999,999 ("k")
[2] = 1,000,000 - 999,999,999 ("M")
[3+] = etc.
And I want to write a function to check if a string is a valid number with one of these suffixes at the end, and then return either a valid number with the suffix removed (1.57k to 1570) or false if the input string can't be converted to a number.
I already have a working version for this, but it's messy and slow and I was unable to figure out how to improve it.
Note: Some of the prefixes start with another prefix, for example, T and TrD or Qa and QaD. And I'd want to always match the full one, not just the first one found.
Edit: The array of possible suffixes can/will change.
I'm taking care of "check if a string is a valid number with a suffix". You will just have to add your calculation function using this given result.
function getSuffix(input){
const [ suffix ] = input.match(/[^\d]+$/) || [];
return suffix;
}
function suffixIsValid(suffix){
if(!suffix){
return false;
}
const suffixes = ["k", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No", "Dc", "UnD", "DuD", "TrD", "QaD", "QiD", "SeD", "SpD", "OcD", "NoD", "Vi", "UnV"];
return suffixes.some(validSuffix => validSuffix.toLowerCase() === suffix.toLowerCase());
}
function isValidNumberWithValidSuffix(input){
const number = parseFloat(input);
const suffix = getSuffix(input);
return !isNaN(number) && (!suffix || (suffix && suffixIsValid(suffix))) ? { number, suffix } : false;
}
console.log(isValidNumberWithValidSuffix(("InvalidNumber")));
console.log(isValidNumberWithValidSuffix(("153InvalidSuffix")));
console.log(isValidNumberWithValidSuffix(("153")));
console.log(isValidNumberWithValidSuffix(("15.3M")));
console.log(isValidNumberWithValidSuffix(("1.53qad")));
I'm new to RegExp and to JS in general (Coming from Python), so this might be an easy question:
I'm trying to code an algebraic calculator in Javascript that receives an algebraic equation as a string, e.g.,
string = 'x^2 + 30x -12 = 4x^2 - 12x + 30';
The algorithm is already able to break the string in a single list, with all values on the right side multiplied by -1 so I can equate it all to 0, however, one of the steps to solve the equation involves creating a hashtable/dictionary, having the variable as key.
The string above results in a list eq:
eq = ['x^2', '+30x', '-12', '-4x^2', '+12x', '-30'];
I'm currently planning on iterating through this list, and using RegExp to identify both variables and the respective multiplier, so I can create a hashTable/Dictionary that will allow me to simplify the equation, such as this one:
hashTable = {
'x^2': [1, -4],
'x': [30, 12],
' ': [-12]
}
I plan on using some kind of for loop to iter through the array, and applying a match on each string to get the values I need, but I'm quite frankly, stumped.
I have already used RegExp to separate the string into the individual parts of the equation and to remove eventual spaces, but I can't imagine a way to separate -4 from x^2 in '-4x^2'.
You can try this
(-?\d+)x\^\d+.
When you execute match function :
var res = "-4x^2".match(/(-?\d+)x\^\d+/)
You will get res as an array : [ "-4x^2", "-4" ]
You have your '-4' in res[1].
By adding another group on the second \d+ (numeric char), you can retrieve the x power.
var res = "-4x^2".match(/(-?\d+)x\^(\d+)/) //res = [ "-4x^2", "-4", "2" ]
Hope it helps
If you know that the LHS of the hashtable is going to be at the end of the string. Lets say '4x', x is at the end or '-4x^2' where x^2 is at end, then we can get the number of the expression:
var exp = '-4x^2'
exp.split('x^2')[0] // will return -4
I hope this is what you were looking for.
function splitTerm(term) {
var regex = /([+-]?)([0-9]*)?([a-z](\^[0-9]+)?)?/
var match = regex.exec(term);
return {
constant: parseInt((match[1] || '') + (match[2] || 1)),
variable: match[3]
}
}
splitTerm('x^2'); // => {constant: 1, variable: "x^2"}
splitTerm('+30x'); // => {constant: 30, variable: "x"}
splitTerm('-12'); // => {constant: -12, variable: undefined}
Additionally, these tool may help you analyze and understand regular expressions:
https://regexper.com/
https://regex101.com/
http://rick.measham.id.au/paste/explain.pl