Simple calculator example using array to store input values - javascript

The input values are stored in an array, the below loop is to calculate the final result, by looping through the array and appending the operators and numbers to a variable which is then evaluated.
privateCalculate = function () {
var total;
for(i = 0; i < init.sequence.length; i++) {
if(init.sequence[i] === "+" || init.sequence[i] === "-" ||
init.sequence[i] === "*" || init.sequence[i] === "/" ||
init.sequence[i] === "(" || init.sequence[i] === ")")
{
total += init.sequence[i];
} else {
init.sequence[i] = parseFloat(init.sequence[i]);
total += init.sequence[i];
}
}
console.log(eval(total));
//console.log((parseFloat(1)+parseFloat(2))/parseFloat(2));
},
The function produces "NaN"

You said your input is: ["5","+","5"]
You don't need to parse it, because evaltakes as parameter a String
Just do this:
var inputArray = ["5","+","5"];
eval(inputArray.join('')) // -> 10

Related

How to check two conditions with && correctly

I want to loop through an array and check if each element is a number OR a string that could potentially turned into a number (e.g. "42"). If it can be "converted" then the element should be stored in a new array.
This is my code where I push all converted elements into a new array. Notice: I also want to count how many elements were "converted" from a string into a number and how many were not.
function numberConverter(arr) {
var converted = []
var counterConverted = 0
var counterNotConverted = 0
for (var c of arr) {
if (typeof c == "string" && Number(c) == "number") {
counterConverted++;
parseInt(c, 10);
converted.push(c)
} else {
counterNotConverted++
}
}
if (counterConverted == 0) {
return "no need for conversion"
} else {
return counterConverted + " were converted to numbers: " + converted + "; " + counterNotConverted + " couldn't be converted"
}
}
I know that my if condition
if(typeof c == "string" && Number(c) == "number")
is flawed logically, but I can't make up why.
Thanks for any hints and please explain it in beginner terms.
You can test if a string could be converted to a number like so:
val !== "" && Number.isNaN(Number(val)) === false
And the code could be written like so:
function numberConverter(arr) {
var converted = [];
var notconverted = [];
arr.forEach(function(val) {
if (typeof val === "number") {
converted.push(val);
} else if (typeof val === "string" && val !== "" && Number.isNaN(Number(val)) === false) {
converted.push(Number(val));
} else {
notconverted.push(val);
}
});
console.log("converted", converted);
console.log("not converted", notconverted);
}
numberConverter([0, "1", "", "123-foo", undefined, null, true, [], {}]);
The best solution is to use a functional approach to the code rather than an imperative one.
let arrayNumbers = ["Vadim", 99, {}, [], "100", "55AA", "AA55", Infinity, "false", true, null, -65.535, 2E1, "2E2"].filter( value => value !== null && value != Infinity && value !== '' && !isNaN(Number(value)) && !['boolean','array','object'].includes(typeof value)).map(value => +value);
console.log('Was Converted to Numbers:', arrayNumbers);
You need to check typeof string and isNaN in ESLint way (Number.isNaN(Number())).
function numberConverter(arr) {
const converted = [];
let counterConverted = 0;
for (let i = 0; i < arr.length; i += 1) {
const str = arr[i];
if (str && typeof str === 'string' && !Number.isNaN(Number(str))) {
const number = parseInt(str, 10);
converted.push(number);
counterConverted += 1;
}
}
const counterNotConverted = arr.length - converted.length;
if (counterConverted === 0) {
return 'No need for conversion.';
}
return `${counterConverted} were converted to numbers: ${converted.join(',')}; ${counterNotConverted} couldn't be converted`;
}
console.log(`'${numberConverter(['id', null, {}])}'`); // No need for conversion.
console.log(`'${numberConverter(['1', '-1', 'val'])}'`); // 2 were converted to numbers: [1,-1]; 1 couldn't be converted
console.log(`'${numberConverter(['1', '-1', '0', '1.5', 'val'])}'`); // 4 were converted to numbers: [1,-1,0,1]; 1 couldn't be converted

recursion with chartCodeAt to reduce string

way to recursion to reduce string or array?
example case:
if we have. variable abcdfgh4zi output must be f4z
BECAUSE after d it must be e and then after h it must be I
it likes sorting...
I am trying it but failed using charCodeAt
function reduce(data) {
let result = ""
if (data.length <= 1) {
return result
} else if (data.charCodeAt(data[0])+1 !== data.charCodeAt(data[1])) {
result += data[0]
}
return result + reduce(data.slice(1))
}
console.log(reduce('abcdfgh4zi')); // f4z
the result is the same like that data, and if I am using it <, it gonna be empty string
if data "lmnop" the result is true and it gonna return empty string because they are sorting
and here to find the next alphabet I found on SO If chartCodeAt doesn't work
var abc = (parseInt(data[0], 36) + 1) % 36;
var nextAlphabet = ((!abc * 10 + abc).toString(36));
charCodeAt expects an index, you are giving it the character. So you are doing data.charCodeAt("a") + 1 !== data.charCodeAt("b")
You are also storing the first character, so you would be storing "d" and not "f"
function reduce(data) {
let result = ""
if (data.length <= 1) {
return result
} else if (data.charCodeAt(0)+1 !== data.charCodeAt(1)) {
result += data[1]
}
return result + reduce(data.slice(1))
}
console.log(reduce('abcdfgh4zi')); // f4z

Specify Range of Numbers Javascript in Conditional Statement

I am sort of new to Javascript Code and I'm wondering how can I specify that x in this case can be a number in between 750 to 850.
else if(DATA == "PULSOUT 12, x") {
*Note DATA is a user input that was taken from a textarea if that info is needed.
#Ahm23, Try this:
if (DATA.substr(0,11) == "PULSOUT 12," && parseInt(DATA.substr(11).trim()) >= 750 && parseInt(DATA.substr(11).trim()) <= 850) {
You can define a function which checks if input is within range 751-849 where array contains elements [750, 850], pass or define array containing ranges at second parameter, use logic n > range[0] && n < range[1], where n is user input. You can use .match(), RegExp /\d+$ to get digits before end of string, `
let x = "750";
function checkX(n, range = [750, 850]) {
return n > range[0] && n < range[1]
}
console.log(checkX(x)); // false
console.log(checkX(x = 751)); // true
console.log(checkX(x = 850)); // false
let DATA = `PULSOUT 12, ${x = 808}`;
console.log(
checkX(x = DATA.match(/\d+$/g).pop())
&& DATA.replace(/\d+$/, "") === "PULSOUT 12, "
); // true

JS calculator issue. Wrong Answer

I'm writing a one-line calculator, that has the basic functions (+ - * /). I have done this before, but now I keep getting wrong answers, and I can't find my mistake. Here is my code:
var seq = document.getElementById('sequence').value;
var allNums = [];
var i = 0, allSigns = [];
var currentNums = "";
for (i = 0; i< seq.length; i++)
{
if (seq[i] != "+" && seq[i] != "-" && seq[i] != "*" && seq[i] != "/")
{
currentNums+=seq[i];
}
else
{
allNums.push(Number(currentNums));
currentNums="";
allSigns.push(seq[i]);
}
}
allNums.push(Number(currentNums));
var result = 0;
for (i = 0; i < allNums.length; i++)
{
if (allSigns[i] == '+')
result+=Number(allNums[i]);
else if (allSigns[i] == "-")
result-=Number(allNums[i]);
else if (allSigns[i] == "*")
result*=Number(allNums[i]);
else if (allSigns[i] == "/")
result/=parseInt(allNums[i]);
else
{
alert("The result is: " + result);
break;
}
}
All of this code is in a function, called calculate. The func is triggered by a button, and the sequence comes from an input.
Though there are numerous shortcomings with this simple calculator that may or may not be a problem (depending on what you want to do with it), one issue is that your allSigns array values aren't being associated with the correct allNums array values.
Take a look at this example. In the console, you can see that the sign associated with the 6 is the plus sign, while the operator associated with 2 is undefined. This isn't what we want, of course. What we want is to add the two to the six.
The fix for this issue would be always adding allNums[0] to the result from the start. This sets up our result to be operated upon by anything following it. In this case, we start off with 6.
Next what we need to do is shift the position of each value of allSigns down by one, lining up the operator with the value after it, and not before it. So, in the example above, we'd have + associated with 2, so it'd add the two to the six.
This JSFiddle shows the fix for this specific case.
http://jsbin.com/obasix/3/edit
There are not as many signs as numbers. So therefore, if there are 2 numbers and 1 sign, it will calculate 5 + and then end.
You should start with the result bring the first number.
And then iterate with the remaining numbers and calculate accordingly.
var seq = "5+4";
var allNums = [];
var i = 0, allSigns = [];
var currentNums = "";
for (i = 0; i< seq.length; i++)
{
if (seq[i] != "+" && seq[i] != "-" && seq[i] != "*" && seq[i] != "/")
{
currentNums+=seq[i];
}
else
{
allNums.push(Number(currentNums));
currentNums="";
allSigns.push(seq[i]);
}
}
allNums.push(Number(currentNums));
var result = allNums[0];
for (i = 1; i <= allNums.length; i++)
{
if (allSigns[i-1] == '+')
result+=Number(allNums[i]);
else if (allSigns[i-1] == "-")
result-=Number(allNums[i]);
else if (allSigns[i-1] == "*")
result*=Number(allNums[i]);
else if (allSigns[i-1] == "/")
result/=parseInt(allNums[i]);
else
{
alert("The result is: " + result);
break;
}
}
Try this library https://github.com/notshekhar/calculate.js
Example
<script src="https://raw.githubusercontent.com/notshekhar/calculate.js/main/calculate.js"></script>
<script>
let add = calculate(1, 1, "+") // add -> 2
let sub = calculate(1, 1, "-") // sub -> 0
let mul = calculate(1, 1, "*") // mul -> 1
let div = calculate(1, 1, "/") // div -> 1
let mod = calculate(1, 1, "%") // mod -> 0
</script>

Format currency using javascript

a script returns either a number like 0.0580 so in x.xxxx format or a (x) for X units left.
I want to format the number 0.0580 and return 5.8 cent or return x units left.
Any ideas how to do that in javascript? Especially how do I format the x.xxxx?
In case the first x is not 0 I want to return e.g. 1.75$.
MS has written a nice plugin for jquery. it's especially useful if you're localizing. Give it a go:
http://weblogs.asp.net/scottgu/archive/2010/06/10/jquery-globalization-plugin-from-microsoft.aspx
I'm not sure if this can be used outside of jquery...
I may be spoiling you here, but whatever. Here's a function that I found somewhere at some point and have been recycling since. I haven't actually bothered to look much into it to figure out what it does exactly, but it has been rather useful:
function FormatMoneyAmount(starting_string, ending_string) {
//check validity of input (true = invalid, false = valid)
var valid_exp = new RegExp ('[^0-9,.$]', 'gi');
input_invalid = (typeof(ending_string) == 'undefined' && valid_exp.test(starting_string));
//check if more than 2 digits follow decimal or no decimal
decimal_invalid = typeof(ending_string) == 'undefined' && (starting_string.indexOf('.') > -1) && ((starting_string.length - starting_string.indexOf('.')) > 3);
if (input_invalid || decimal_invalid) {
ending_string = starting_string;
} else {
//remove commas, dollar signs
var replace_exp = new RegExp ('[,$]', 'gi');
starting_string = starting_string.replace(replace_exp, '');
//remove decimal if ending string not set, save for adding on later
var decimal_substring = '';
if (typeof(ending_string) == 'undefined' && starting_string.indexOf('.') > -1) {
decimal_substring = starting_string.substring(starting_string.indexOf('.'), starting_string.length);
remaining_string = starting_string.substring(0,starting_string.indexOf('.'));
} else {
remaining_string = starting_string;
}
//if string is already 3 characters or less, do nothing
if (remaining_string.length > 3) {
//separate last 3 characters of string from rest of string
var final_three = remaining_string.substring(remaining_string.length - 3, remaining_string.length);
remaining_string = remaining_string.substring(0, remaining_string.length - 3);
//if not first group of 3, add new group before old group with comma, else set to new group
ending_string = (typeof(ending_string) == 'undefined') ? final_three + ((typeof(decimal_substring) == 'undefined') ? '' : decimal_substring) : final_three + ',' + ending_string;
//call function again if more than 3 digits remaining to process, else add to end string
if (remaining_string.length > 3) {
ending_string = FormatMoneyAmount(remaining_string, ending_string);
} else {
ending_string = remaining_string + ',' + ending_string;
}
} else {
ending_string = (typeof(ending_string) == 'undefined') ? remaining_string : remaining_string + ',' + ending_string + ((typeof(decimal_substring) == 'undefined') ? '' : decimal_substring);
}
}
return ending_string;
}
The first thing to do is check the format of the string, since you will have two code paths depending on the result:
if (typeof num = "string" && num.slice(0,1) == "(" && num.slice(-1) == ")") {
// String is in the format (x), so we just need to return that number
return num.slice(1,-1) + " units left";
}
The next part is to check if the number is less than 1, indicating that it is cents and not whole dollars. If it is less than 1, multiplying it by 100 will give you the number of cents you're after:
if (+num < 1)
// 0.0580 * 100 = 5.8
return (num * 100) + " cents";
else
return +num + "$";

Categories