Javascript Object negative number - javascript

Create object adjustementType inside script tag in MVC 5 partial view.
<script type="text/javascript">
var adjustementType = { -1:'Rate Decrease', 1: 'Rate Increase' };
</script>
but getting following error "Expected identifier, string or number" . The error is thrown on area -1 & 1 field.

You cannot use strings with spaces because you are defining variables and you also should turn type around like this:
var adjustementType = { RateDecrease: -1, RateIncrease: 1 };
alert(adjustementType.RateDecrease); //-1
This is because you are actually defining enums.
EDIT: You can use strings with spaces too but then you are dealing with them like arrays. But I think this doesn't make any sense.
var enumtype = { "-1": "Rate Decrease", "1" : "Rate Increase"};
alert(enumtype["1"]); //Rate Increase
alert(enumtype["-1"]); //Rate Decrease

Since -1 is not valid identifier you need to take such keys into quotes when you define an object properties:
var adjustementType = { '-1': 'Rate Decrease', 1: 'Rate Increase' };
then you will be able to access it using bracket notation:
alert(adjustementType[-1]);

Related

eval() triggers Unexpected number when part of string passed into it has decimal

The below works perfectly until a key is sent to it with a decimal in it. Then it triggers an "Unexpected number". I can think of some work arounds that have to do with modifying the keys in the object sent from the database, but want to figure out why this triggers an error first.
What is happening in the below:
A number of percentiles are sent from the FE by the user (e.g., 5th, 15th, 35th, 62.5th, etc.) as an object (e.g. incP1: 5th, incP2: 15th, etc.) which are then mapped.
If the key starts with inc it does a certain set of logic.
It constructs a string (fieldStr) that corresponds with a key in the cr object which is basically the actual values of the percentiles the user requested.
In this case it would construct something like cr.TestInc15
The let fieldObj = eval(fieldStr) then returns the value from cr. of the key that was constructed.
Hopefully that makes sense, but that is why I am using eval() because I can't get the value from just the key as string otherwise. It works fine until it hits something like the 62.5th percentile where the key would be constructed as cr.TestInc62.5 which definitely has a value in cr. as I can console.log it out.
renderData(percentiles, cr, varName) {
return (
_.map(
_.pickBy(percentiles, function (value, key) {
return _.startsWith(key, 'inc')
}), p => {
let fieldStr = 'cr.' + varName + 'Inc' +
(p == 'n' ? 'N' :
(p == 50 ? 'Median' : p
));
// a bunch of junk after this, but error stops it here
let fieldObj = eval(
fieldStr
);
}
)
)
}
Of course you can get the value with a string, you can access an object property without using eval even in your case of having dots as part of property names.
It's called bracket notation
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
var cr = { "TestInc62.5": "Val123" }
console.log(cr["TestInc62.5"]);

JavaScript - Matching alphanumeric patterns with RegExp

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

How to avoid parsing address as float in Javascript

I am working on javascript code that parses a tab delimited document. In order to facilitate searching I need to convert those properties that are a number to a float. However, mixed fields (like an address) should maintain the status of a String.
for(var i2=0;i2<line1.length;i2++){
var test = local[i2];
if(! (typeof test === 'undefined')){
test = test.trim();
};
var parsed = parseFloat(test);
if(!isNaN(parsed)){
if(line1[i2] === "Site Address")
console.log("Number before:"+local[i2]+" After:"+parsed);
object[line1[i2]]=parsed;
}
else{
if(line1[i2] === "Site Address")
console.log("before:"+local[i2]+" After:"+test);
object[line1[i2]]=test;
}
}
This seems to work ok unless there are both numbers and chars like the following....
Number before:1752 E MAIN ST After:1752
Is there a way to do this where the above is not seen as explicitly a number?
You can use the unary + operator:
var parsed = +test;
The parseFloat() function is OK with strings that start with a valid number that's followed by non-numeric stuff, as you've discovered.
If that seems too "hackery" you can also use the Number constructor:
var parsed = Number( test );
You haven't provided very much test data, so answers may not be very good. You can try using a regular expression so that only things that look like numbers are treated as numbers, e.g.
var isNum = /^\d+(\.\d+)?$/;
var test = line1[i2];
parsed = isNum.test(test)? parseFloat(test) : test;
The variable "test" would probaby be better named "item" or "value" or similar.

Using an asterisk* as a key in an object

I'm getting an error trying to use an asterisk as a key reference of an object. I've tried formatting different ways, but always get the same error:
SyntaxError: missing name after . operator
Here is my code with an object rendered from the wikipedia api...
The line in question is:
console.log(shortcut.langlinks[index].*);
var wp = {
"query":{
"pages":{
"3823":{
"pageid":3823,
"ns":0,
"title":"Binary",
"extract":"<p><b>Binary</b> means <i>composed of two pieces or two parts</i> and may refer to:</p>\n\n",
"links":[{
"ns":0,"title":"Binary-coded decimal"},{
"ns":0,"title":"Binary (Assemblage 23 song)"},{
"ns":0,"title":"Binary code"}],
"langlinks":[{
"lang":"de","*":"Bin\u00e4r"},{
"lang":"fr","*":"Binaire"},{
"lang":"ur","*":"\u062a\u062b\u0646\u06cc\u06c1"}]
}
}
}
};
var page_key = Object.keys( wp['query']['pages'])[0];
var shortcut = wp['query']['pages'][page_key];
function translation() {
if (shortcut.langlinks.length > 0){
for (var index in shortcut.langlinks){
if (shortcut.langlinks[index].lang == 'de'){
console.log(shortcut.langlinks[index].*);
}
}
} else {
console.log("There are no language links.");
}
}
How do I format my code to get the asterisk to display like a key value?
Thanks.
You can use brackets as well:
shortcut.langlinks[index]['*']
When you want to access a property whose name is also a valid name for an identifier you can use the dot syntax: shortcut.langlinks (langlinks is a valid identifier name).
When the property name is not a valid identifier name, you must use the angle bracket syntax instead: langlinks[index]["*"] (* is not a valid identifier name because it does not start with "$", "_", or any Unicode character that is classed as a letter).
You can use:
console.log(shortcut.langlinks[index]['*']);

Eval alternative

This code works as a calculator, but the scratch pad at codeacademy tells me that eval is evil. Is there another way to do the same thing without using eval?
var calculate = prompt("Enter problem");
alert(eval(calculate));
eval evaluates the string input as JavaScript and coincidentally JavaScript supports calculations and understands 1+1, which makes it suitable as a calculator.
If you don't want to use eval, which is good, you have to parse that string yourself and, finally, do the computation yourself (not exactly yourself though). Have a look at this math processor, which does what you want.
Basically what you do is:
Read the input string char by char (with this kind of problem it's still possible)
Building a tree of actions you want to do
At the end of the string, you evaluate the tree and do some calculations
For example you have "1+2/3", this could evaluate to the following data structure:
"+"
/ \
"1" "/"
/ \
"2" "3"
You could then traverse that structure from top to bottom and do the computations.
At first you've got the "+", which has a 1 on the left side and some expression on the right side,
so you have to evaluate that expression first. So you go to the "/" node, which has two numeric children. Knowing that, you can now compute 2/3 and replace the whole "/" node with the result of that. Now you can go up again and compute the result of the "+" node: 1 + 0.66. Now you replace that node with the result and all you've got left is the result of the expression.
Some pseudo code on how this might look in your code:
calculation(operator, leftValue, rightValue):
switch operator {
case '+': return leftValue + rightValue
case '-': return 42
}
action(node):
node.value = calculation(node.operator, action(node.left) action(node.right))
As you might have noticed, the tree is designed in such a way that it honors operator precedence. The / has a lower level than the +, which means it get's evaluated first.
However you do this in detail, that's basically the way to go.
You can use the expression parser that is included in the math.js library:
http://mathjs.org
Example usage:
mathjs.evaluate('1.2 / (2.3 + 0.7)'); // 0.4
mathjs.evaluate('5.08 cm in inch'); // 2 inch
mathjs.evaluate('sin(45 deg) ^ 2'); // 0.5
mathjs.evaluate('9 / 3 + 2i'); // 3 + 2i
mathjs.evaluate('det([-1, 2; 3, 1])'); // -7
You can use eval safely for a simple arithmetic calculator by filtering the input- if you only accept digits, decimal points and operators (+,-,*,/) you won't get in much trouble. If you want advanced Math functions, you are better off with the parser suggestions.
function calculate(){
"use strict";
var s= prompt('Enter problem');
if(/[^0-9()*+\/ .-]+/.test(s)) throw Error('bad input...');
try{
var ans= eval(s);
}
catch(er){
alert(er.message);
}
alert(ans);
}
calculate()
I write some functions when I had a problem like this. Maybe this can help:
data = [
{id:1,val1:"test",val2:"test2",val2:"test3"},
{id:2,val1:"test",val2:"test2",val2:"test3"},
{id:3,val1:"test",val2:"test2",val2:"test3"}
];
datakey = Object.keys(data[0]);
// here's a fix for e['datakey[f]'] >> e[x]
vix = function(e,f){
a = "string";
e[a] = datakey[f];
x = e.string;
end = e[x];
delete e.string;
return end;
};
// here's a fix to define that variable
vox = function(e,f,string){
a = "string";
e[a] = datakey[f];
x = e.string;
end = e[x] = string;
delete e.string;
};
row = 2 // 3th row ==> {id:3,val1:"test",val2:"test2",val2:"test3"}
column = 1 //datakey 2 ==> val1
vox(data[row],column,"new value");
alert(data[2].val1); //the value that we have changed

Categories

Resources