Looping through arrays and checking their values - javascript

What I have done is that I have firstly I have parsed them with the jQuery function, $.parseJSON() and so now I am having 2 arrays with 3 objects inside them. What I want to do is that I want to loop over both the arrays at the same time so that I could check the Post_IDs of the current object in the loop of both the arrays that if they are equal or not and then if I find that the Post_ID is not present there already or there is a mismatch then I want to do something.
Here's what I have done:
var posts = <? php echo $posts; ?> ;
setInterval(function () {
$.get("admin/post/get_new_posts.php", {
userId: <? php echo User::GetUserID($_SESSION["username"]); ?>
}, function (data) {
data = $.parseJSON(data);
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < posts.length; j++) {
if (posts[j].Post_ID != data[i].Post_ID) {
//do something...
} else {
}
}
}
});
}, 10000);
The posts variable has its value and I am sure about it by logging them into the console. Now what happens here is that every ten seconds a get request is sent and checks if the Post_ID meets of the posts variable object does not equal the Post_ID of the data variable then do something in there. But that's not the case. The condition is always going true.
And yes, here are my objects. The first one is the posts variable and the second one is the data variable.
Any idea of how can I loop through both the variables or arrays and check for a property at the same time while looping?

You're comparing every entry in posts to every entry in data. Most of those won't match - posts[0] won't match data[1], data[2], etc.
It sounds like you want to look at the corresponding members of each list (posts[0] vs. data[0], etc.)
In that case, you need one loop, not two.
// find the longest array's length
var maxi = Math.max(posts.length, data.length, 0);
for ( var i = 0; i < maxi; ++i )
{
if (i >= posts.length)
{
// an entry in data, but not posts
}
else if (i >= data.length)
{
// an entry in posts, but not data
}
else if (data[i].Post_ID != posts[i].Post_ID)
{
// mismatched IDs
}
else
{
// matched IDs
}
}

You are executing two loops and this creates a problem. because they have the following meaning (I'm gonna translate them into pure english):
for each item of array 'data', check any item in array 'posts' that is not equal to the current item of 'data'. This is why it is always "doing something".
Since both arrays have the same length, you should do one loop like this :
for (var i = 0; i < data.length; i++) {
if (posts[i].Post_ID != data[i].Post_ID) {
//do something...
} else {
}
}

Related

Skipping multiple elements in a FOR loop, Javascript

I have some file contents I'd like to pass on to my server using a javascript function. In the file, there are many empty lines, or those which contain useless text. So far I read every line in as a string stored in an array.
How do I then loop through that content skipping multiple lines such as lines 24,25, 36, 42, 125 etc. Can I put these element id's into an array and tell my for loop to run on every element except these?
Thanks
you can't tell your for loop to iterate all, but skip certain elements. it will basically just count in any direction (simplified) until a certain critera has been met.
you can however put an if inside your loop to check for certain conditions, and chose to do nothing, if the condition is met. e.g.:
(pseudo code below, beware of typing errors)
for(var line=0; line < fileContents.length; line++) {
if(isUselessLine(line)) {
continue;
}
// process that line
}
the continue keyword basically tells the for loop to "jump over" the rest of the current iteration and continue with the next value.
The isUselessLine function is something you'll have to implement yourself, in a way, that it returns true, if the line with the given linenumber is useless for you.
You can try this its not much elegent but will suerly do the trick
<html>
<body>
<p>A loop which will skip the step where i = 3,4,6,9.</p>
<p id="demo"></p>
<script>
var text = "";
var num = [3,4,6,9];
var i;
for (i = 0; i < 10; i++) {
var a = num.indexOf(i);
if (a>=0) {
continue;
}
text += "The number is " + i + "<br>";
}
document.getElementById("demo").innerHTML = text;
</script>
</body>
You could use something like this
var i = 0, len = array1.length;
for (; i < len; i++) {
if (i == 24 || i == 25) {
array1.splice(i, 1);
}
}
Or you can have an another array variable which got all the items that need to be removed from array1
Another method:
var lines = fileContents.match(/[^\r\n]+/g).filter(function(str,index,arr){
return !(str=="") && uselessLines.indexOf(index+1)<0;
});
If you have many indices to skip, and this depends on the elements of the array, you could write a function that returns the number of elements to skip over for each index in that array (or returns 1, if no skipping required):
for ( let i = 0;
i < array.length;
i += calcNumberOfIndicesToSkip( array, i )){
// do stuff to the elements that aren't
// automatically skipped
}
function calcNumberOfIndicesToSkip( array, i ){
// logic to determine number of elements to skip
// (this may be irregular)
return numberOfElementsToSkip ;
}
In your case:
// skip the next index (i+1)?
for ( let i=0; i<array.length; i+=skipThisIndex(i+1) ){
// do stuff
}
function skipThisIndex(i){
const indicesToSkip = [ 24, 25, 36, 42, 125 ];
return 1 + indicesToSkip.includes(i);
}
// returns 1 if i is not within indicesToSkip
// (there will be no skipping)
// => (equivalent to i++; normal iteration)
// or returns 1 + true (ie: 2) if i is in indicesToSkip
// => (index will be skipped)

javascript : after calling the splice() control comes out from the loop

I have an array rosters and i want to alter this array according to some conditions. Here what I'm trying to do.
somefunction(callback) {
for (var i in this.rosters) {
var roster = this.rosters[i];
if (roster.age > 7200) {
this.rosters.splice(i, 1);
} else {
this.rosters[i].age = this.EMarshal.tu.getAgeOfTime(
this.EMarshal.tu.getMyTime(
this.EMarshal.tu.getMyDate(roster.date), roster.shifttime
)
);
console.log(this.rosters[i].age);
}
}
callback();
}
When the the if condition is true and splice is been called, control comes out of from loop and call callback(). But i want to run the loop for each values in the array.
plz carefully notice that there are rosters and roster 2 different variables.
Any idea why its happening and the solution will be usefull.
Thanks
It's just because you are trying to alter the array on which you are iterating.
So, just ad some logic to store the indexes as you have said you have tried.
Here is one suggestion
before getting into loop var index = [];
then your if condition
if (roster.age > 7200) {
index.push(i);
}
and then after the loop, remove those indexes from rosters
for (var j = index.length - 1; j > -1; j-- ) {
console.log(j);
this.rosters.splice(index[j], 1);
}
Remember to iterate the index from last index otherwise you will remove the 1st index and the trying to remove the last index from the rosters, but now you have removed the element from the array so the length is been changed.

Javascript 2D Array Loop Stopping

Im writing a program to which I need to retrieve values from multiple input boxes and stash them in a 2D array so that I can $.post them to a php file.
The problem is, the loop seems to stop upon reaching "scoresScores[j][k] = $(this).val;" part. But whenever I comment out that part, it will loop just fine. What seems to be the problem?
UPDATE: It's not just the loop that stops, all the code below scoresScores doesn't get executed.
if(flag){
studIDs = [];
scoreScores = [[]];
pScores = [];
$(".studID"+term).each(function(i){
studIDs[i] = $(this).text();
for(var j = 0; j < countTypes; j++){
pScores[j] = $("#txtPScoreEdit"+term+"-"+j).val();
$(".txtScoreEdit"+term+"-"+j).each(function(k){
if(k == i){
scoreScores[j][k] = $(this).val();
}
});
}
});
when($.post("/res/php/editScores.php",{
studIDs: studIDs,
scoreSubjEDP: <?php echo $_GET['EDPCode']?>,
scoreTerm: term,
scoreScores: scoreScores,
pScores: pScores
})).done(function(){
location.reload();
});
}
It's because scoreScores only has one nested array # index === 1
So when you loop and j > 0 or k > 0 it will fail.
You just need to make sure the indexes are valid.
edit:
If sparse arrays are OK, the following should work:
if(k == i){
if(!scoreScores[j]) { scoreScores[j] = []; }
scoreScores[j][k] = $(this).val();
}

How can I pick data out of an array in a object and insert it into another array in an object in Javascript?

I have variable qstore that's has an ans array containing a list of responses. The field named r is used to hold the response data (true or false) and is stored in an array called ans
qstore: {"id":2,
"qId":2,
"ans":[{"r":true},
{"r":true},
{"r":false},
{"r":false},
{"r":false}]}
Another variable qview:
qview: {"problemId":2,
"questionId":1,
"answer":null,
"text":"xx",
"answers":[{"answerId":1,
"response":false},
{"answerId":2,
"response":false},
{"answerId":3,
"response":false},
{"answerId":4,
"response":false},
{"answerId":5,
"response":false}]}
What I need to do is IF there is an array called ans in qstore (there may not be one) then I need to take the answer responses field r and use that to update the answers response field in the qview object. Note that the qview and qstore if they do have answers will always have the same number of answers.
Can anyone tell me a simple way that I can do this?
What I need to do is IF there is an array called ans in qstore (there may not be one) then I need to take the answer responses field r and use that to update the answers response field in the qview object. Note that the qview and qstore if they do have answers will always have the same number of answers.
// assuming `qstore`, `qview`
var i, j, ans = qstore.ans;
if (ans) { // if qstore has non-falsy ans
qstore: for (i = 0, j = 0; i < ans.length; ++i) { // loop over ans
for (; j < qview.answers.length; ++j) { // look in qview
if (qview.answers[j].answerId === i + 1) { // qview has already
qview.answers[j].response = ans[i].r;
continue qstore; // go back to looping ans
} else if (qview.answers[j].answerId <= i) { // qview needs new
break; // get out of qview loop
}
} // if we reach here then qview didn't have an entry for this item
qview.answers.splice(j, 0, { // insert new entry
'answerId': i + 1,
'response': ans[i].r
});
}
}
Just simply loop over the qstore.ans array (if it exists) and set the respective value in qview.
if(qstore.hasOwnProperty('ans')){
for(var i = 0, len = qstore.ans.length; i < len; i++){
qview.answers[i].response = qstore.ans[i].r;
}
}
JavaScript has an multiple ways to check if a key exists in an object: in and Object.hasOwnProperty. The difference between the two is that in also returns true if the key is found in the prototype chain of your object.
Now it appears the id's of your response are 1-indexed, but that doesn't matter if we iterate over the index of its position in the array itself:
if ('ans' in qstore) {
for (var i = 0; i <= qstore.ans.length; i++) {
qview.answers[[i].response = qstore.ans[i].r
}
}
There's also a nicer forEach available, if you're not expecting to support IE8 and earlier, or are prepared to insert a "shim":
if ('ans' in qstore) {
qstore.ans.forEach(function(element, index) {
element.response = qstore.ans[index].r
})
}
The most simple solution.
This way it will execute only if you have at less, 1 register on ans array, i see that the solutions above do not verify if the ans array have registers, so i think it is the right one for your case.
Here is the code:
if (qstore.ans != null){
if (qstore.ans.length > 0){
for (i=0;i<qstore.ans.length);i++){
qview.answers[i].response = qstore.ans[i].r;
}
}
}

Javascript indexing array issue

Hi I have an array that hold the following numbers, however when I loop though the eachNode function(which iterates 13 times) it repeats all the list elements 13 times. I tested everything but it still produces an error, I'm I executing the for loop correctly?
list[61,67,78]
var len = list.length;
fd.graph.eachNode(function (node) { // loops thru all node id's in graph (13)
for (var i = 0; i < len; ++i) {
if (i in list) {
var nody = list[i]; // I put the number in a variable
var nodess = fd.graph.getNode(nody); //this takes the number and matches it with a node id, it "odjectify" it
if (node.id != nodess.id) { // if the list nodes are not the same
node.setData('alpha', 0); //
node.eachAdjacency(function (adj) { // this make the unmatched nodes disappear
adj.setData('alpha', 0, 'end');
});
}
}
}
});
This line is unneeded:
if (i in list)
The in keyword returns true if its right operand contains the property specified by its left operand. When using this with arrays, it returns unexpected results. The behavior of this keyword is insignificant in this context, so you should simply take it out.
Moreover, you need to create the list array like this:
var list = [61, 67, 78];
...however, when I loop though eachNode (which iterates 13 times) it repeats all the list elements 13 times
It doesn't, it in fact iterates over eachNode 13 times. You also made a for loop which will traverse the list array by its length.
Now that you've given me more detail as to what you want, here is the updated code. I hope it works for you:
fd.graph.eachNode(function (node) {
var flag = false;
for (var i = 0; i < len; ++i)
{
var nody = list[i];
var nodess = fd.graph.getNode(nody);
if (node.id == nodess.id) {
flag = true; break;
}
}
if (flag)
{
node.setData('alpha', 0);
node.eachAdjacency(function (adj) {
adj.setData('alpha', 0, 'end');
});
}
});
This is the behavior by design:
You loop over the graph (13 times as you say), then inside each iteration you loop over your array (3 items).
If you only want to loop once over your array, just move it out of the outer loop

Categories

Resources