I have a loop to check collision between objects in my game, all the objects are collected in the same Array. I use a code like this to match every object with eachother:
for (var i = 0; i < objs.length; i++) {
for (var j = i + 1; j < objs.length; j++) {
collision(objs[i], objs[j]);
}
}
Now this does not seem to actually perform all collisions with eachother, I've noticed that it skips some too..
Then I came up with this solution:
for (var i = 0; i < objs.length; i++) {
for (var j = 0; j < objs.length; j++) {
if (j != i) {
collision(objs[i], objs[j]);
}
}
}
This solution seem to not have any problems, but I wonder if there is any kinda way to not have to use the if (j != i) statement, or is there maybe a totally different solution?
Soo, who's correct eh..?
It depends on the definition of collision in your game.
If collision is a symmetric function (i.e. A collides with B if, and only if, B collides with A), then use:
for (var i = 0; i < objs.length; i++) {
for (var j = i + 1; j < objs.length; j++) {
collision(objs[i], objs[j]);
}
}
because there's no need to check (B,A) if you checked (A,B) before.
But if it is possible to make A collide with B without making B collide with A, or vice versa, then you must check all possible different pairs, so use
for (var i = 0; i < objs.length; i++) {
for (var j = 0; j < objs.length; j++) {
if (j != i) {
collision(objs[i], objs[j]);
}
}
}
Related
Description of problem in code. Why it is going on??
var response = JSON.parse(xhr.responseText);
console.log(response[0].conversationUsers.length); //OK, console outputs "2"
for (i = 0; i < response.length; i++) {
for (j = 0; j < response[i].conversationUsers.length; j++) { //Error 'cannot read property', but it has to be interpreted "j = 0; j < 2; j++" and it worked in console.log
...
}
}
UPD. I've added temporary variable and it works.
for (j = 0; j < response[i].conversationUsers.length; j++) //this way doesn't work
var temp = response[i].conversationUsers;
for (j = 0; j < temp.length; j++) //this way works
Question can be closed, but any ideas why so?
You are using console.log() for only the first object in that array. I suggest you try:
var response = JSON.parse(xhr.responseText);
for (i = 0; i < response.length; i++) {
console.log(response[i].conversationUsers); // should be an array
for (j = 0; j < response[i].conversationUsers.length; j++) {
...
}
}
If you get any undefined in your console, while doing this, you have identified your problem.
The thing is that for the first element in the array response[0].conversationUsers has a value that is an array. That might not be true for every element in that array and therefore some of those elements might not have a length property.
You are trying to iterate inside length property. Try to remove length. Like this
var response = JSON.parse(xhr.responseText);
console.log(response[0].conversationUsers.length);
for (i = 0; i < response; i++) {
for (j = 0; j < response[i].conversationUsers; j++) {
...
}
}
I have a function that has a nested for loop. As the function iterates over more data, it is starting to slow down. How can I best optimize this function so that it runs a bit faster?
function rubicoGVB(arr, range) {
var res = [];
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if ((arr[i] + arr[j]) / range < 16487665) {
res.push(arr[i]);
}
}
}
return res.length;
}
(The biggest improvement you could make is described by Fast Snail in this comment: You don't need the res array just to return its length; simply use a counter. Below are other improvements you could make.)
Looking at those loops, there's very little you can do other than:
Caching the length of the array, and
Caching arr[i] instead of looking it up repeated in the j loop
...which are minimal (but real) improvements, see len and entry below:
function rubicoGVB(arr, range) {
var res = [];
var len = arr.length;
var entry;
for (var i = 0; i < len; i++) {
entry = arr[i];
for (var j = i + 1; j < len; j++) {
if ((entry + arr[j]) / range < 16487665) {
res.push(entry);
}
}
}
return res.length;
}
I'm having some issues on how to read arrays.
console.log(arr[i][j]); -- Can someone explain how the i and j fit into this. I'm printing the array i and j to the console, correct?
function multiplyAll(arr) {
var product = 1;
// Only change code below this line
var i = 0;
var j = 0;
for (i = 0; i < arr.length; i++ ) {
for (j = 0; j < arr[i].length; j++) {
console.log(arr[i][j]);
product *= arr[i][j];
}
}
// Only change code above this line
return product;
}
// Modify values below to test your code
multiplyAll([[1,2],[3,4],[5,6,7]]);
You are printing the j-th element of the i-th array to the console.
As we know, we can omit the initialization inside the for loop :
var i = 0;
for(; i < 10; i++) {
// do Something with i
}
However, i figure out if i omit the initialization inside the nested loop as well:
var i = 0;
var j = 0;
for(; i < 10; i++) {
for(; j < 10; j++) {
// only do Something with j
// outner loop only run once
}
}
Solution :
var i = 0;
var j;
for(; i < 10; i++) {
j = 0;
for(; j < 10; j++) {
// everything is fine!
}
}
Can anyone explain whats going on? I'm newbie in Javascript.
The loop runs multiple times, but your 'j' is already ten after the first run of i, so the second loop no longer runs during the next values of i.
If you would write something like this.
for(; i < 10; i++) {
for(; j < 10; j++) {
console.log("test")
}
console.log("another test")
}
You would see that both messages get printed 10 times.
The reason that your "j" loop, only runs "ten times once", is because you do not set J back to zero after it has run 10 times. So the statement j < 10is true for every loop if iafter the first run.
You could solve this by setting j = 0 inside the first for loop (if you do not want to put it inside the variable initialisation of the second loop.)
for(; i < 10; i++) {
j = 0;
for(; j < 10; j++) {
console.log("test")
}
console.log("another test")
}
Every time i increments, you need to reset j to 0.
If you rewrite your script so that each variable is initialised within the for loop statement itself, then every time i increments, j will be reset to 0.
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
}
}
I have a parse background job that contains a simple query.each for one class. This class has 2 Arrays field filled with objects.IDs. Inside this query, for every single object, i need to check if the objects.ID of the first Array are contained in the second Array.
Basically in a simple loop:
var j = 0;
for (var j = 0; j < firstArray.length; j++) {
if(firstArray[j] "isContainedIn" secondArray){
// my custom code
}
}
What i can't figure out is the function to use, if exist..Does javascript have a function like that or i need to make a nested loop to achieve my goal?
EDIT: i worked it out using indexOf but the solution proposed by Shqiptar didn't work so here is the one that actually works:
first Array name = usersEligibleToVote
second Array name = usersThatVoted
for (var j = 0; j < usersEligibleToVote.length; j++) {
if(usersThatVoted.indexOf(usersEligibleToVote[j]) === -1){
console.log("user.id "+usersEligibleToVote[j]+" needs to vote");
} else {
console.log("user.id "+usersEligibleToVote[j]+" has voted");
}
}
var j = 0;
for (var j = 0; j < firstArray.length; j++) {
if(firstArray[j].contains(secondArray))
{
// your custom code here
}
}
And then for checking if an object is the same :
var j = 0;
for (var j = 0; j < firstArray.length; j++) {
if(firstArray[j].indexOf(secondArray) != -1)
{
// your custom code here
}
}
I would process it through a simple jQuery and javascript for loop like so:
var arr1;
var arr2;
var i;
for(i = 0; i < arr1.length; i++) {
if ($.inArray(arr1[i], arr2) {
break; //do things here or what not
}
}