How to add sum of currency values of an array in javascript - javascript

how to add currency values of an array like this
array = [ '$0',
'$0',
'$14,792',
'$152,445',
'$1,581,033',
'$2,988,978',
'$4,226,419',
'$7,254,960',
'$10,726,945',
'$12,657,402',
'$35,215,787',
'$37,968,368',
'$7,648,445',
'$364,237',
'$390,395',
'$306,080',
'$3,641,253',
'$4,328,363',
'$1,360,664' ]
here is my method defined, the only problem i am facing is in the second for array_sum is not adding the values that i am getting from data variable.
exports.GetMonthsFWSeasonFullSeasonValues = () => {
var promises = [];
var array_sum = 0;
for(var month_index = 9; month_index <= 27 ; month_index++){
const elm_xpath = utils.GetXpathForSubCategory(chosen_season_index, month_index);
promises.push(element(by.xpath(elm_xpath)).getText());
}
return Promise.all(promises).then(function(data){
if(data != null) {
for (var array_index = 0; array_index < data.length; array_index++){
array_sum += data[array_index];
console.log('sum of values from months',array_sum);
}
} else {
return null;
}
});
};

The problem here is that you are trying to add two strings. The + operator is overloaded in JS, so with numbers it adds them, but with strings it concatenates them. You need to convert them to ints or floats by using parseInt or parseFloat, and get rid of the commas and $ signs out of it, something like:
var num = '$1,100'
parseInt(num.replace(/[$,]/g, ''))
Which would give 1100 if you printed it. After they are in number format, you can sum them.
Or if you have the choice to store the numbers in your array as numbers, without the string formatting to start off with, go with that. So much easier.

Related

Combine an array with other arrays, push each combination Javascript

I'm trying to take an array, and compare each value of that array to the next value in the array. When I run my code, components that should match with more than one array only return one match, instead of all of them. I'm probably doing something wrong somewhere, but for the life of my I don't seem to be able to figure it out.
This is my code:
INPUT
minterms = [["4",[0,1,0,0]],
["8",[1,0,0,0]],
["9",[1,0,0,1]],
["10",[1,0,1,0]],
["12",[1,1,0,0]],
["11",[1,0,1,1]],
["14",[1,1,1,0]],
["15",[1,1,1,1]]];
Function
function combineMinterms(minterms) {
var match = 0;
var count;
var loc;
var newMin = [];
var newMiny = [];
var used = new Array(minterms.length);
//First Component
for (x = 0; x < minterms.length; x++) {
if(minterms[x][1][minterms[x][1].length - 1] == "*") {
newMin.push(minterms[x].slice());
continue;
};
//Second Component
for (y = x + 1; y < minterms.length; y++) {
count = 0;
//Compare each value
for (h = 0; h < minterms[x][1].length; h++) {
if (minterms[x][1][h] != minterms[y][1][h]) {
count++;
loc = h;
}
if (count >= 2) {break; };
}
//If only one difference, push to new
if (count === 1) {
newMin.push(minterms[x].slice());
newMiny = minterms[y].slice();
newMin[match][1][loc] = "-";
while(newMin[match][0].charAt(0) === 'd') {
newMin[match][0] = newMin[match][0].substr(1);
}
while(newMiny[0].charAt(0) === 'd') {
newMiny[0] = newMiny[0].substr(1);
}
newMin[match][0] += "," + newMiny[0];
used[x] = 1;
used[y] = 1;
match++;
continue;
}
}
//If never used, push to new
if(used[x] != 1) {
newMin.push(minterms[x].slice());
newMin[match][1].push("*");
match++;
}
}
return newMin;
}
Desired Output
newMin = [["4,12",[-,1,0,0]],
["8,9",[1,0,0,-]],
["8,10",[1,0,-,0]],
["8,12",[1,-,0,0]],
["9,11",[1,0,-,1]],
["10,11",[1,0,1,-]],
["10,14",[1,-,1,0]],
["12,14",[1,1,-,0]],
["11,15",[1,-,1,1]],
["14,15",[1,1,1,-]]];
It will combine term 8, with 9 but won't continue to combine term 8 with 10, 12
Thanks in advance for the help.
Array.prototype.slice performs a shallow copy.
Each entry in minterms is an array of a string and a nested array.
When you slice the entry, you get a new array with a copy of the string and a copy of the Array object reference. But that copy of the Array reference still points to the array contained in an element of minterms.
When you update the nested array
newMin[match][1][loc] = "-";
you are updating the nested array within the input. I never fathomed the logic of what you are doing, but I believe this is the problem, with solution of cloning the nested array (as well) when cloning an input array element.
A secondary issue you will probably wish to fix is that not all variables were declared: var x,y,h; or equivalent inline declarations are missing.
let minterms = [4,8,9,10,12,11,14,15];
let newMin = [];
minterms.map((value, index) =>{
minterms.reduce((accumulator, currentValue, currentIndex, array) => {
accumulator = value;
let out = (accumulator ^ currentValue).toString(2);
if(out.split('').filter(n=>n==="1").length == 1) newMin.push([value, currentValue]);
}, value);
});
console.log(newMin);
There is a better approach (in 10 lines of code). Since you're working with binary representations, you might want to consider using BitWise operators. When coupled with array operators it makes most of this straight forward.
For instance:
Given a match means only a single bit differs between two binary numbers:
The bitwise XOR operator returns 1 for each bit that doesn't match. So:
0100 XOR 1000 results in 1000
Now, we need to count the number of '1' digits in the binary number returned. We can use the length property of an array to do this. To turn 1000 into an array, first we turn the binary into a string:
The binary representation of the integer 4 is easily retrieved with:
num.toString(2)
So if num === 4, the output above is the string "0100".
Now we use str.split() to turn the string into an array. Remove everything from the array that is not a '1'. Now simply get the length property. If the length === 1, it is a match.
I put together a solution like this for you. It is close to your use case. I didn't use the funny dash style in the output because that was not part of your question.
https://jsbin.com/xezuwax/edit?js,console

Sorting odd and even numbers with the remainder operator Javascript

If a number, when divided by two, has a remainder that is not equal to 0, this number must be odd. I'm trying to use that logic in my if statement to keep only odd values, and get rid of even ones. I'm not sure how I'm doing this wrong, but myArray is returning even values as well as odd. Any ideas?
function sumFibs(num) {
var myArray = [1,1];
// Create fibonacci sequence
// Stop creating fibonacci numbers at num
// Push odd numbers to oddNums array
for (var i = 0; i < myArray.length; i++) {
if (myArray[i+1] + myArray[i] <= num && myArray[i+1] + myArray[i] % 2 !== 0) {
myArray.push(myArray[i+1] + myArray[i]);
}
} // End loop.
console.log(myArray);
// Summation of oddNums array.
return myArray.reduce(function(a,b) {
return a + b;
});
} // End function.
sumFibs(1000);
You are trying to filter odd values while generating your fib sequence, which probably not the best approach. If you wrap the modulo expression in parentheses,
(myArray[i+1] + myArray[i]) % 2
Your array will not contain the values necessary to continue generating the sequence. Ideally you should generate the full fib series and then filter:
var myArray = [1,1];
for (var i = 0; i <= num; i++) {
myArray.push(myArray[i+1] + myArray[i]);
} // End loop.
myArray = myArray.filter(function(a){ return a%2 !== 0 })
or save some reference to the even values so that they can be used to calculate the desired subset of the series.

Get the value for each control from a list of elements?

I'm struggling to get the input value from a control in JavaScript, and I think it may have something to do with the collection of controls I'm looping through.
My page consists of many input controls with decimals in them. I'm only interested in controls starting with the name 'txtinput', and I need to tally up the values in each one. However, when I do this with the code below, all I seem to be getting out is a JSON looking string for each element.
function TallyPoints() {
var eles = [];
var inputs = document.getElementsByTagName("input");
var total = 0;
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].name.indexOf('txtpoints') == 0) {
total += document.getElementsByName(inputs[i].name)[0].value;
}
}
alert('Total: ' + total.toString());
};
What I end up with is a value that looks like this:
Total: 0{"enabled":false,"emptyMessage":"","validationText":"333.33","valueAsString":"333.33","minValue":-70368744177664,"maxValue":70368744177664,"lastSetTextBoxValue":"333.33"}{"enabled":false,"emptyMessage":"","validationText":"5.66","valueAsString":"5.66","minValue":-70368744177664,"maxValue":70368744177664,"lastSetTextBoxValue":"5.66"}
Any ideas?
You probably want parseFloat() so your addition works properly (fiddle):
var inputs = document.querySelectorAll("input[name^=txtpoints]");
var total = [].reduce.call(inputs, function (p, c) {
return p + (parseFloat(c.value) || 0);
}, 0);
See also parseInt(), isNaN(), and Array.prototype.reduce()
Try this:
function TallyPoints() {
var inputs = document.getElementsByTagName("input");
var total = 0;
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].name.indexOf('txtpoints') == 0) {
var val = parseFloat(inputs[i].value);
if (!isNaN(val)) {
total += val;
}
}
}
alert('Total: ' + total);
};
parseFloat is needed to convert the input from a string to a number, so that + will do addition rather than concatenation. There's no need to use getElementsByName, since you already have the element in inputs[i]. There's no need to use total.toString(); concatenating a number to a string converts it automatically.
The if (!isNan(val)) test skips over the inputs that don't contain numbers.
You could also use document.querySelectorAll('input[name^=txtpoints]') to find the relevant input elements in one step.

Getting range from a list using regular expressions

I have a list of numbers such as
var list = ["123","12345678","123","234,2345","2.34567","123.12345","-123","-0.1234","-324215.45"];
This list can have negative, positive numbers with optional decimal values, also negative or positive.
I need to use regular expressions to do 3 things:
getAllNumbersBeforeValue(value);
getAllNumbersAfterValue(value);
getRangeBetweenValues(valueFrom, valueTo);
Value passed in is not known, could be any number.
Update 1:
I've got this, which isn't perfect but works on some numbers:
var a = function(rand) {
var val = "";
var numArr = rand.split("");
for(var i = 0; i < numArr.length; i++) {
val = val + (Number(numArr[i])+1);
}
return "^[^" + val.split("").join("-9][^") + "-9]$"
}; // outputs "^[^2-9][^3-9][^4-9][^5-9][^6-9]$" with rand "12345"
Im trying to get a regular expression programmatically generated from a given value
For example "123456" is a random number (rand), I would like to be able to filter an array of numbers for values that are higher then rand (or lower then rand) using a regex value.
Thanks
You could use underscore.js (http://underscorejs.org) to filter your results. For example...
var list = ["123","12345678","123","234,2345","2.34567","123.12345","-123","-0.1234","-324215.45"];
function getAllNumbersBeforeValue(list, value) {
return _.filter(list, function(num) {
return num < value;
});
}
Here's an example without using a framework...
function getAllNumbersBeforeValue(list, value) {
var output = [];
for(var i = 0; i < list.length; i++) {
if(list[i] < value) {
output.push(list[i]);
}
}
return output;
}
getAllNumbersBeforeValue(list, 123);

Comparing 2 arrays to output total integer

I have 2 arrays of numbers. I want to go through each array and find the number of times 1 number from each array adds up to the particular amount x.
If the particular amount x is reached as many times as another set number n then the function should print 'YES'. If x does not reach the set number of n then the function should print 'NO'.
The values of x , n and both arrays are in a string input. These values have been split into arrays as seen below in the code.
I have set up 2 for loops to run through each array and an if statement that checks for the condition of x meeting n.
The arrays I'm using in this code should print out the result of 'YES' however every time I run the code I'm getting 'NO' ? I've tried tinkering with the code but nothing has worked.
Any idea on where this code is broke and how to fix the problem?
Thanks :)
code:
var input = '2\n3 10\n2 1 3\n7 8 9';
function processData(input) {
var inputArray = input.split('\n');
var n = inputArray[1][0];
var x = inputArray[1].split(' ')[1];
var arrayA = inputArray[2].split(' ');
var arrayB = inputArray[3].split(' ');
var total = 0;
for(var i = 0; i < arrayA.length; i++) {
for(var j = 0; j < arrayB.length; j++) {
if(arrayA[i] + arrayB[j] == x) {
total = total + 1;
} if (total == n) {
return 'YES';
}
}
}
return 'NO';
}
console.log(processData(input));
arrayA[i] and arrayB[j] are strings, so arrayA[i] + arrayB[j] will be the concatenation of them (ex: '2' + '3' === '23').
If your logic is correct (i didn't quite understand what you are trying to do), it should be enough to convert them to numbers before adding them, using parseInt or some other method:
if(+arrayA[i] + (+arrayB[j]) == +x) { // used unary + to convert to number
total = total + 1;
} if (total == n) {
return 'YES';
}
PS: A cleaner version would be to convert each string in the array to number, but that involves more than adding 3 characters to your code.
PS2: You have a weird way of getting the input data. If you get it from another place in your JS code, you could simply pass it as an object with the relevant structure, otherwise you could pass it around in a more ... common format, like JSON.

Categories

Resources