JavaScript; I want to get the values in a string which always has the following format but also has an indeterminate number of variables:
Sample String "340=5;339=5;338=3;337=4;336=1;335=4;334=4;333=4"
The variables named as 340, 339, 338 etc. in this string store integer values such as 5, 4, 1 and so on. I want to extract the integer values for each of the variables (extracting what's after the equal signs) and store the sum and average value of them in two separate variables as "sum" and "avr".
Nothing fancy, hopefully nice and readable.
function calculate(myString) {
var values = myString.split(';');
var sum = 0;
values.forEach(function(el, i) {
sum += parseInt(el.split('=')[1]);
});
return {
sum: sum,
avg: sum / values.length
}
}
var results = calculate("340=5;339=5;338=3;337=4;336=1;335=4;334=4;333=4");
console.log(results.sum); // => 30
console.log(results.avg); // => 3.75
As you have a simple pattern, you can use a RegExp to find the bits of interest. Here is an example using String.prototype.split and Array.prototype.reduce
var str = "340=5;339=5;338=3;337=4;336=1;335=4;334=4;333=4";
var parts = (';'+str).split(/;\d+=/).slice(1), // passing the RegExp to .split
sum = parts.reduce(function(prev, cur) {
return prev + +cur; // notice String cur to Number
}, 0),
avr = sum / parts.length; // assuming you want mean average
console.log(sum, avr); // 30 3.75
I would split the string then loop through all the values to get the sum and average.
var str="340=5;339=5;338=3;337=4;336=1;335=4;334=4;333=4";
var array =str.split(/;?\d+=/g);
var sum=0;
for(i=0;i<array.length;i++){
if(!isNaN(parseInt(array[i])))
sum+=parseInt(array[i]);
else{
array.splice(i,1);
i--;
}
}
console.log(sum);
console.log(sum/array.length);
This is trivial string evaluation. The only method you need is split, and the only logic you need is a for loop.
var values = "340=5;339=5;338=3;337=4;336=1;335=4;334=4;333=4";
var sum = []
var avr = []
values = values.split(';');
for(i=0; i<values.length; i++){
numbers = values[i].split('=')
sum.push(numbers[0])
avr.push(numbers[1])
}
Related
I have a function that I have modified to get a string (which consists of zeros and ones only).
The string (timesheetcoldata):
100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000
The string items (the numbers one and zero) will change every time the function is run.
It will always be the same length.
I have made the string above easier to see what I am trying to achieve.
I want to return the first character and then every 24th character (as in the variable colsCount in the function).
so, in the example above, it would return something like: 111111
I then want to convert these characters to numbers (something like [1, 1, 1, 1, 1, 1]).
I then want to sum these number together (so it would return, in the example: 6).
I then want to check if the returned number matches the variable: rowsCount
or true if it does, false if it does not.
My function:
$("#J_timingSubmit").click(function(ev){
var sheetStates = sheet.getSheetStates();
var rowsCount = 6;
var colsCount = 24;
var timesheetrowsdata = "";
var timesheetcoldata = "";
for(var row= 0, rowStates=[]; row<rowsCount; ++row){
rowStates = sheetStates[row];
timesheetrowsdata += rowStates+(row==rowsCount-1?'':',');
}
timesheetcoldata = timesheetrowsdata.replace(/,/g, '');
console.log(timesheetcoldata);
});
Thank you very much to both Rajesh and MauriceNino (and all other contributers).
With their code I was able to come up with the following working function:
$("#J_timingSubmit").click(function(ev){
var sheetStates = sheet.getSheetStates();
var rowsCount = 6;
var timesheetrowsdata = "";
var timesheetcoldata = "";
for(var row= 0, rowStates=[]; row<rowsCount; ++row){
rowStates = sheetStates[row];
timesheetrowsdata += rowStates+(row==rowsCount-1?'':',');
}
timesheetcoldata = timesheetrowsdata.replace(/,/g, '');
var count = 0;
var list = [];
for(var i = 0; i< timesheetcoldata.length; i+=24) {
const num1 = Number(timesheetcoldata.charAt(i));
list.push(num1);
count += num1;
}
let isSameAsRowsCount = count == rowsCount;
console.log('Is Same? ', isSameAsRowsCount);
});
You can always rely on traditional for for such action. Using functional operations can be more readable but will be more time consuming(though not by much).
You can try this simple algo:
Create a list that will hold all numbers and a count variable to hold sum.
Loop over string. As string is fixed, you can set the increment factor to the count(24).
Convert the character at given index and save it in a variable.
Push this variable in list and also compute sum at every interval.
At the end of this loop, you have both values.
var string = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
var count = 0;
var list = [];
for(var i = 0; i< string.length; i+=24) {
const num1 = Number(string.charAt(i));
list.push(num1);
count += num1;
}
console.log(list, count)
Here is a step by step explanation, on what to do.
Use match() to get every nth char
Use map() to convert your array elements
Use reduce() to sum your array elements
Everything needed to say is included in code comments:
const testData = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
// Step 1) Create array of numbers from string
const dataArr = testData.match(/.{1,24}/g) // Split on every 24th char
.map(s => Number(s[0])) // Only take the first char as a Number
console.log(dataArr);
// Step 2) Sum array Numbers
let dataSum = dataArr.reduce((a, b) => a + b); // Add up all numbers
console.log(dataSum);
// Step 3) Compare your variables
let rowsCount = 123; // Your Test variable
let isSameAsRowsCount = dataSum == rowsCount;
console.log('Is Same? ', isSameAsRowsCount);
As #Jaromanda mentioned, you can use the following to done this.
const string = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
const value = string.split('').filter((e,i)=> !(i%24)).reduce((acc,cur)=> acc+ (+cur), 0);
console.log(value);
I am trying to sum the contents of an array like these:
var cardsBen = [10,2]
var cardsAmy = [4,10]
When I use a for loop, it works.
for(var i = 0; i < cardsBen.length; i++){
cardsBen[i] = Number(cardsBen[i]);
}
When I use forEach, it doesn't convert.
cardsAmy.forEach(function(item)
{
Number(item);
});
I know this because, when I then reduce the arrays, I get 12 for Ben and 410 for Amy.
var sumBen = cardsBen.reduce(function(sum, nbr){return sum + nbr});
var sumAmy = cardsAmy.reduce(function(sum, nbr){return sum + nbr});
Primitive values can't be mutated. So when doing Number(item) you have to assign that back to the array like:
cardsAmy.forEach(function(item, i) {
cardsAmy[i] = Number(item);
});
And you can do that directly in reduce (without needing the above forEach code) like:
var sumBen = cardsBen.reduce(function(sum, nbr) { return sum + Number(nbr); }, 0);
// ^^^^^^^ ^
You could use reduce with an implicit casting to number with an unary plus +.
sum = array.reduce(function (s, v) {
return s + +v;
}, 0);
I'm trying to sum and then average a stream of data, some code here.
var getAverage = function(dataArray){
var total,
sample = dataArray.length,
eArray = Array.prototype.slice.call(dataArray);
for (var i = 0; i< sample; i++) {
total+= eArray[i];
}
return total;
}
var output = function(){
//source data
var dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);
var average = getAverage(dataArray);
$('#average').text(average);
window.requestAnimationFrame(output);
Every element in the array returns a number, but it still returns NaN. Help?
Set total = 0; currently it is defaulting to undefined. undefined + a number = NaN, and NaN + a number = NaN.
The declared variable total is undefined which means it will create NaN (Not-a-Number) when a number is added to it.
Also, Typed Array (ArrayBuffer/views) and Array are not the same, and converting a typed array to an ordinary Array is making iteration slower as typed arrays are actual byte-buffers while Arrays are (node) lists. That on top of the cost of conversion itself.
Just add them straight forward. Remember to divide the sum on length and of course to initialize total:
var getAverage = function(dataArray){
var total = 0, // initialize to 0
i = 0, length = dataArray.length;
while(i < length) total += dataArray[i++]; // add all
return length ? total / length : 0; // divide (when length !== 0)
}
I want to calculate a total from the values in an array.
I've tried several different approaches, but starting to struggle with the wonders of number calculations in JS.
As an example, this is my array:
["0.20", "1.20"]
and how i've been trying to get a total from these values:
var totalPrice = 0;
var arrLength = arr.length;
while(arrLength--)
totalPrice += parseFloat(Math.round(arr[arrLength] * 100) / 100).toFixed(2);
However, this returns 01.200.20.
If I modify the array to have only one value, 0.20, this returns 00.20.
How can I get a total value from the array that will retain the decimal places?
JSFiddle
FYI - the fiddle also contains some objects which generate the array, if an item is set to true.
You are doing string concatenation instead of adding the floats. Just use the parseFloat, then get your decimal places at the end when you need the actual string representation.
var arr = ["0.20", "1.20"];
var totalPrice = 0;
var arrLength = arr.length;
while (arrLength--) {
totalPrice += parseFloat(arr[arrLength]);
}
document.getElementById("result").innerHTML = totalPrice.toFixed(2);
<div id="result">x</div>
function function1() {
arr = document.getElementById("textfield").value;
arr = arr.split(",");
length = arr.length;
largestNum = -9999;
for (i = 0; i < length; i++) {
if (arr[i] > largestNum) {
largestNum = arr[i];
}
}
alert("Largest number: " + largestNum);
}
can someone tell me what the hell is going on here, i have no idea why it's giving me 8 instead of 12
http://jsfiddle.net/qkLpA/15/
edit - fixed here: http://jsfiddle.net/qkLpA/12/
You're splitting a string, so each element of the resulting array will be a string. When you compare strings, it goes character-by-character, and 8 is larger than 1, so it never goes on to the 2.
The solution is to convert the items into numbers after splitting it:
arr = arr.split(",").map(function(s) { return parseInt(s, 10); });
If the map is confusing, you could also be less fancy and just use a for loop to convert them:
arr = arr.split(",");
for(var i = 0; i < arr.length; i++) {
arr[i] = parseInt(arr[i], 10);
}
You may also want to consider using -Infinity as the initial largestNum rather than -9999.
There's a much shorter way to get the largest humber:
function function1() {
var arr = document.getElementById("textfield").value;
arr = arr.split(",");
var max = Math.max.apply(null, arr);
alert("Largest number: " + max);
}
Fiddle
Your problem is that the .split() of the textfield string, creates an array of strings and not numbers. As a consequence, your comparison if (arr[i] > largestNum) in the for loop, is in reality a lexicographical comparison of strings, instead of a numerical comparison of integers, as you might have thought. That is why the "8" is larger than the "12".
You can confirm this in the updated jsfiddle which converts the strings to integers before comparing.