I'm trying to get a function to loop through data in two tables and put them into an object. The first for-loop that goes through the first table does this fine, but the second for-loop that goes through the second table spits out an empty object when there's only 1 row to go through.
However, when there is more than 1 row, then all of the objects have the values as the second row.
I really don't understand what I'm doing wrong here:
function foo(){
var rows = $('#table1').find('tr');
var array1 = [];
for(var i = 1; i < rows.length-1; i++){
var row = $(rows[i]).find('input');
var o = {
name : $(row[0]).val(),
bday : $(row[1]).val(),
parent : $(row[2]).val(),
parentBDay : $(row[3]).val(),
parentNumber : $(row[4]).val()
};
array1.push(o);
}
var array2 = [];
rows = $('#table2').find('tr');
for(var j = 1; j < rows.length-1; j++){
var row = $(rows[i]).find('input');
var o = {
name : $(row[0]).val(),
bday : $(row[1]).val(),
phoneNumber : $(row[2]).val()
};
console.log('wtf: ' + JSON.stringify(o));
array2.push(o);
}
}
Your problem is that your indexes in the for cycle are not looping well. You start the for cycle from 1, which, in case you want to use the very first element, then it is wrong. Note, that indexing begins from 0. If you miss the very first element on purpose, because it is a header row or something, then this is not a problem. However, the end sign, like
< rows.length - 1
is clearly wrong. Let's suppose, the number of rows is 50. Then its last index is 50 - 1 = 49. If you loop from one until you reach the number below 50 - 1, then your last index will be 48 and you will miss the very last element. Your condition should be either < rows.length or <= rows.length - 1.
Related
I'm using Adobe Livecycle Designer ES4 to create some report. Based on XML a try to fill table. I have problem with Array. I push data into array in for loop. Below examples of my code:
Results - blank textbox
var print_data = xfa.record.containerPrintingData;
var sfcArray = [];
for (var i = 0; i < 10; i++) {
sfc = print_data.resolveNode("sfcPrintingData["+ i +"]").sfc.value;
sfcArray.push(sfc);
};
this.rawValue = sfcArray.toString();
Results - get all items
var print_data = xfa.record.containerPrintingData;
var sfcArray = [];
for (var i = 0; i < 10; i++) {
sfc = print_data.resolveNode("sfcPrintingData["+ i +"]").sfc.value;
sfcArray.push(sfc);
this.rawValue = sfcArray.toString();
}
Results - get 2nd item x 10
var print_data = xfa.record.containerPrintingData;
var sfcArray = [];
for (var i = 0; i < 10; i++) {
sfc = print_data.resolveNode("sfcPrintingData[1]").sfc.value;
sfcArray.push(sfc);
this.rawValue = sfcArray.toString();
}
Why 1st example don't work and 2nd work correct? I need use this array in another loops. How to solve it?
Because, If it has 2 items, and you looping it for 10.
What happends is, when this.rawValue = sfcArray.toString(); is inside the loop, this.rawValue gets updated 2 times. First time One item will be there. second time 2 items.
For the next iteration there is no 3rd item. So code breaks with error. But this.rawValue still have 2 items.
Where as, when this.rawValue = sfcArray.toString(); is outside the loop, the code breaks with error and this.rawValue don't have any items in it.
I have a simple array
var answerAttribute = ['A','B','C','D'];
I have 16 list items, what I'm trying to accomplish is loop through the length of the list and regardless of if the list 2 items or 300. I'd lke to have a data attribute associated with it of A,B, C or D.
Here's what I'm working with:
var questionOption = '';
for(var i = 0; i < quizContent.length; i++) {
questionOption = answerAttribute[i % answerAttribute.length];
console.log(questionOption);
}
When logging this to the console, it logs A, AB, ABC, ABCD, ABCDundefined, and keeps repeating undefined until it's reached the loops conclusion. My question is what am I doing incorrectly so that it only logs one letter per loop.
questionOption += answerAttribute[i]
This statement is short-form for questionOption = questionOption + answerAttribute[i]. It will append the next element to questionOption in every iteration of the loop.
It looks like what you want is probably questionOption = answerAttribute[i]. This will replace the value in questionOption with the new element instead of appending it.
You could simply log only the current value, like this:
var questionOption = '';
for (var i = 0; i < quizContent.length; i++) {
//what is questionOption used for?
questionOption += answerAttribute[i];
console.log(answerAttribute[i]);
}
or if you want questionOption to refer to the current value
questionOption = answerAttribute[i];
console.log(questionOption );
You're looping the quizContent indexes and applying them to the answerAttribute array. I believe what you want is a nested loop...
var quizContent = Array(10); // assume you have 10 quiz questions...
var answerAttribute = ['A','B','C','D'];
for (var i = 0; i < quizContent.length; i++) {
// generate a string for each quiz option
var questionOption = '';
for (var n = 0; n < answerAttribute.length; n++) {
questionOption += answerAttribute[n];
}
quizContent[i] = questionOption;
console.log(questionOption);
}
console.log(quizContent);
Somehow I doubt that the question is actually about the logging, and is actually about the resulting string.
Either way, I'd do this without loops.
var answerAttribute = ['A','B','C','D'];
var quizContent = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
var questionOption = answerAttribute
.join("")
.repeat(Math.ceil(quizContent.length / answerAttribute.length))
.slice(0, quizContent.length);
console.log(questionOption);
It just joins the answerAttribute into a string of characters, and repeats that string the number of times that the length of answerAttribute can be divided into quizContent.length (rounded up).
Then the final string is trimmed down to the size of the quizContent to remove any extra content from the rounding up.
Note that this approach assumes a single character per attribute. If not a single, but they're all the same length, it can be adjusted to still work.
So I'm trying to just make a ".replace" loop, but something mysterious is happening.
var cell = "r1c1";
for (i = 0; i <= 4; i++){
cell = cell.replace(cell[3],i+1);
My expected output:
cell = "r1c1"
cell = "r1c2"
cell = "r1c3"
cell = "r1c4"
cell = "r1c5"
The actual output:
cell = "r1c2"
cell = "r2c1"
cell = "r2c3"
cell = "r2c4"
cell = "r2c5"
As you can see, it runs normal EXCEPT for the second iteration.
What in the world am I doing so wrong?
cell.replace(cell[3], i+1) is going to replace the first instance of the '1' character it finds in the string 'r1c1'. In this case it is the '1' at position 1 that gets replaced instead of the '1' at position 3.
To get the results you want, try
var cell = "r1c1";
for (i = 0; i <= 4; i++){
cell = cell.substring(0, cell.length-1)+(i+1);
}
You can use a regular expression: /^r(\d+)c(\d+)/:
var row_col = 'r1c1';
var match = /^r(\d+)c(\d+)/.exec(row_col); // match string
var row = +match[1]; // extract row
var col = +match[2]; // extract column
// edit row and col as needed
row_col = 'r' + row + 'c' + col; // "reassemble" string
This will take care of bigger row/column numbers than 9. If that is not to be expected, then read about String.prototype.substring():
var row_col = 'r1c1';
var row = +row_col.substring(1,2);
var col = +row_col.substring(3,4)
I don't like this, but the fix I ended up using looks like this:
cell = "r"+(j)+cell.substr(2,2);
Since I'm inevitably answering my own question, here, I still want to ask for comments:
How elegant would you say a solution like this is in the long run?
I am trying to make a for loop such that the value 0 will change to 1 if either of the first two values matches the previous row in the array.
So for example, row 2 and row 3 will have the 0 value change to 1, because row 1 has the values of 1 and 3, which matches one of the two values in row 2 and 3.
Following such a case, all the value 0 will all change to 1 eventually (since row 4 will have values of row 2 and 3).
How can I create such a loop?
edgeArray=[[1,3,0],
[1,4,0],
[2,3,0],
[2,4,0]]
for(var counter = 1; counter =< edgeArray.length; counter ++ {
if current edgeArray[i][j][0] && previous edgeArray[i][j][0] on same row && edgeArray[i][j][0] ==
then edgeArray[i][j][0] = edgeArray[i][j][1]
The end result to be
edgeArray=[[1,3,0],
[1,4,1],
[2,3,1],
[2,4,1]]
Not sure I understand fully, but is this what you want??
for(var i = 1; i <= edgeArray.length; i ++) {
// for each row (from second row onwards)
if ( edgeArray[i][0] == edgeArray[i-1][0]
// is the first val the same as prev row?
|| edgeArray[i][1] == edgeArray[i-1][1]
// or second val same as prev row?
|| edgeArray[i-1][2] == 1) {
// or is there already a '1' in 3rd col of prev row?
edgeArray[i][2] = 1;
// in that case change 3rd column to '1'
}
}
If you don't want to 'carry over' the previous 1s to future rows, and you just want the 3rd column to reflect only the previous two rows, then just get rid of the third disjunctive condition in the if statement.
Not sure I understand your requirement, but this results the way you want:
var edgeArray = [[1,3,0],
[1,4,0],
[2,3,0],
[2,4,0]];
var temp = [[],[]];
for(var i=0; i<edgeArray.length; i++){
for(var j=0; j<2; j++){
var found = temp[j].indexOf(edgeArray[i][j]);
if(found > -1){
edgeArray[i][2] = 1;
}else{
temp[j].push(edgeArray[i][j]);
}
}
console.log(edgeArray[i].toString())
}
I have an JS Array that is supposed to show only one element. It does, however its index is 1 rather than 0 and the count is 2. Also the array does not show a 0 index.
My code:
var _UnitOfMeasureRelatedUnitData = [];
var rows = $('#jqxUOMRelatedUnitsDropdownGrid').jqxGrid('getrows');
var RecordCount = 0;
if (rows.length !== 1 && rows[0]["UOMRelatedUnit_Name"] !== ""){
for(var i = 0; i < rows.length; i++){
var row = rows[i];
var _row = {};
if(row.UOMRelatedUnit_AddItem !== F) {
RecordCount += 1;
_row["Name"] = $("#txtUnitOfMeasureSetName").val();
_row["Active"] = T;
_row["UnitOfMeasureTypeID"] = $("input[type='radio'][id='rblUnitOfMeasureType']:checked").val();
_row["BaseUnitID"] = $("input[type='radio'][id='rblUnitOfMeasureBaseUnit']:checked").val();
_row["RelatedUnitDisplayOrder"] = RecordCount;
_row["RelatedUnitName"] = row.UOMRelatedUnit_Name;
_row["RelatedUnitAbbreviation"] = row.UOMRelatedUnit_Abbreviation;
_row["RelatedUnitConversionRatio"] = row.UOMRelatedUnit_ConversionOfBaseUnits;
_row["UnitOfMeasureSetID"] = UnitOfMeasureSetID;
_UnitOfMeasureRelatedUnitData[i] = _row;
}
}
....
}
In my JQx Grid, I have at least four choices. For this issue, Ive only selected the 2 choice in the Grid and its AddItem value is True, everything else is False.
What do I need to change in my logic as I can not see it at this point?
EDIT 1
I overlooked the placement of RecordCount += 1;, I will try moving it to the end of the assignments and see what happens.
EDIT 2
The placement made no difference.
Maintain another variable for indexing your data like this
var index=0; // place this outside of for loop
_UnitOfMeasureRelatedUnitData[index++] = _row;
you don't need RecordCount += 1; .
you can get the rowscount by using _UnitOfMeasureRelatedUnitData.length