I have the following sort function:
var timeArray = new Array('11:41', '11.39', '11:41', '11:41', '11:40', '11:70', '11:39', '11:38', '11:38', '11:37', '11:37');
timeArray.sort(function(c, d) {
var digit1 = parseInt(c.replace(/\D/g,''));
var digit2 = parseInt(d.replace(/\D/g,''));
return digit1 > digit2;});
var testContent = '';
for (var i = 0; i < timeArray.length; i++) {
testContent += timeArray[i] + '<br />';
}
$('#test').html(testContent);
Where I would expect to see the following result:
11:37
11:37
11:38
11:38
11.39
11:39
11:40
11:41
11:41
11:41
11:70
However, the 11.70 number always appears at the top of the results. If I change the 11:70 value in the array, no matter what value I use that is the one that will always appear at the start of the results.
Does anyone know how I can sort this properly and why the 11:70 always appears at the top of the list?
Example Fiddle
Change the sort function to
timeArray.sort(function(c, d) {
var digit1 = parseInt(c.replace(/\D/g,''));
var digit2 = parseInt(d.replace(/\D/g,''));
return digit1 - digit2;
});
FIDDLE
It's expecting a number to be returned, not a boolean.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
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'm trying to inserting the values of counter into an array called numpay.Unfortunately nothing happens.Where's my mistake?Here's what i tried below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example-1</title>
</head>
<body>
<p id="demo"></p>
<script>
function validateForm() {
var months=(principal+principal*interestrate*0.01)/monthlypayment;
var numpay = new Array(months);
for(var i=0;i<=months-1;i++)
{
numpay.push(i);
text += numpay[i] + "<br>";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</body>
</html>
Fixing existing problems
As others have pointed out, something like this should work:
var months = 12;
var numpay = []; // just as easy
var text = "";
for (var i = 1; i <= months; i++) {
numpay.push(i);
text += numpay[i - 1] + "<br/>";
}
document.getElementById('demo').innerHTML = text;
<p id="demo">(empty)</p>
Enhancing your skills
Although you're combining them in your for-loop, you're doing two separate things here: filling out the months, and creating the text you want to add to the DOM.
There's a lot to be said for one bit of code doing only one thing. You could write a reusable range function which uses more modern JS techniques to give you a numeric integer range between two values. So
const range = (lo, hi) => [...new Array(hi - lo + 1)].map((_, i) => i + lo);
Using that, you can create your months variable by calling this function:
const months = range(1, 12);
Then, with this array, you can use Array.prototype.join to combine the values into the text you would like:
const text = months.join('<br/>')
And that leads to a nicer bit of code:
const range = (lo, hi) => [...new Array(hi - lo + 1)].map((_, i) => i + lo);
const months = range(1, 12);
document.getElementById('demo').innerHTML = months.join('<br/>');
<p id="demo">(empty)</p>
If you need that text variable for something additional, then just assign it as the result of the join, and then assign the innerHTML to it.
Obviously that range function is unnecessary. You could just write const months = [...new Array(12)].map((_, i) => i + 1);. But thinking in terms of such abstractions often lets you write cleaner code.
1.) By creating an array like that (new Array(12)) you are saying to create 12 undefined entries in the array. Then you are pushing to the end of the array.
2.) You also need to initialize text with months var months = 12, text;.
var months = 12, text;
var numpay = new Array(months);
for(var i=1; i<=months; i++){
numpay[i] = i;
text += numpay[i] + "<br>";
}
document.getElementById("demo").innerHTML = text;
This will still give you undefined at index 0 but I will leave that for you to work out. But doing numpay[i] = i will overwrite your undefined that was created with the array.
Arrays in JS are zero-based, so if you do .push(i) with i === 1, the value 1 goes into the slot for numpay[0].
And then to access that item, you must use numpay[i-1].
Another thing is that you seem to have forgotten to declare and initialize text before the loop starts. You need to do that, if not then the variable only exists inside the loop body (and loses its value each time the loop body ends).
Demo:
var months = 12;
var numpay = []; // just as easy
var text = "- ";
for (var i = 1; i <= months; i++) {
numpay.push(i);
text += numpay[i - 1] + " - ";
}
console.log(text);
When you instantiate an array with a parameter like this:
var numpay = Array(12);
it results in an array with 12 undefined elements. When you push a new item, it will be placed in the 13th slot.
Instead, just do this:
var text = "";
var months=12;
var numpay = [];
for(var i=1;i<=months;i++)
{
numpay.push(i);
text += numpay[i-1] + "<br>"; //use i-1 here, not i
}
document.getElementById("demo").innerHTML = text;
The result is:
"1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>"
I am trying to create a reverse function to the String type in javascript. My code is like
String.prototype.reverse = function () {
var s = "";
for(var i=this.length;i>=0;i--){
s+=this[i];
}
return s;
}
When I try to use it on for example like "test".reverse();
instead of giving "tset" it's giving "undefinedtset"
I am setting the variable like var s = ""; inside the function, still undefined is coming. Why is it so?
You just need to change var i=this.length to var i=this.length-1, because an array starts at position 0 :
String.prototype.reverse = function () {
var s = "";
for(var i=this.length-1;i>=0;i--){
s+=this[i];
}
return s;
}
this.length gives you 4 (4 letters in test word) and you start iterating from 4 to 0.
The problem is that nothing exists under 4 index (your letters are stored in 0-3 positions).
Try with:
for (var i = this.length - 1; i >= 0; i--) {
s += this[i];
}
The reason why your code isn't working has been answered by the others already, but if you want a shorter version of the reverse, you can do it like this:
String.prototype.reverse = function(){
return this.split('').reverse().join('');
}
console.log('Hello World'.reverse())
I have an object and need to sum/average of each dynamic span. Can't seem to convert those to numbers though. Please Help.
Console Log
Code Sample
Expand/Collapse Created : 1/3/2017 <span>(10)</span>
Expand/Collapse Created : 1/4/2017 <span>(38)</span>
Expand/Collapse Created : 1/5/2017 <span>(13)</span>
Expand/Collapse Created : 1/6/2017 <span>(35)</span>
Expand/Collapse Created : 1/9/2017 <span>(46)</span>
Expand/Collapse Created : 1/10/2017 <span>(17)</span>
Expand/Collapse Created : 1/11/2017 <span>(27)</span>
var arr = [];
$(".ms-gb span").each(function(index, elem){
arr.push($(this).text());
});
$("#result").text(arr.join("+")); // (10)+(38)+(13)+(35)+(46)+(17)+(27)
var allNumbers = document.getElementById('result').innerText; // (10)+(38)+(13)+(35)+(46)+(17)+(27)
allNumbers = allNumbers.replace(/["'()]/g,""); // 10+38+13+35+46+17+28
var newString = allNumbers.split("+"); // Object - ["10", "38", "13", "35", "46", "17", "27"]
well you're pretty close. i'd recommend using the reduce function
var sum = allNumbers.reduce(function(a,b){ return +a + +b; }, 0)
the plus signs in front of a and b might look weird, but its a quick way to coerce a string into a number in javascript
You can strip out non-numeric characters, parse each number, and then perform the addition within the loop.
// variables
var sum = 0;
var average = 0;
var numOfSpan = $('span').length;
// each span loop
$('span').each(function(key, val){
// add the value of the span to the sum var
sum+= parseInt($(this).text().replace(/\D/g,''));
// on the last itteration ...
if(key == (numOfSpan - 1)) {
// calulate average
average = sum / numOfSpan;
// log sum and average
console.log('sum = ' + sum);
console.log('average = ' + average);
}
});
<span>(10)</span>
<span>(38)</span>
<span>(13)</span>
<span>(35)</span>
<span>(46)</span>
<span>(17)</span>
<span>(27)</span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You have to iterate your array and then change every string to number. After that you can add every elements to itself.
var a = 0;
for(var i=0;i<newString.length;i++) {
a += parseInt(newString[i]);}
And then a will be the sum
I'm trying to get array index by value.
I have this code:
var squares = new Array();
for (var i = 1; i <= 160; i++) {
squares.push(i);
}
angular.element('.click').click(function () {
var squareId = angular.element(this).attr('id');
var fisk = squares.indexOf(squareId);
console.log(fisk);
});
This only returns -1, thus, It can't be found. If a replace squareId with a number in indeOf, it works perfect, but if I use a variable, It don't work.
Anyone who can help me?
You are initializing your array values with numbers between 1 and 160, so squares.indexOf(1) for example would return 0.
What you want to do is initialize the array with the actual ids of your elements.
See Example Fiddle
It's because the variable squareId could be returning a string value. The function indexOf can't find the string because it has numbers in the array.
// string search
var squareId = '2';
var fisk = squares.indexOf(squareId);
console.log('This will not be found ' + fisk);
// number search
var squareId = Number('2');
var fisk = squares.indexOf(squareId);
console.log('This will be found ' + fisk);
See similar question