I am writting a simple metaballs implementation in JS. I have an array of the metaballs and i iterate through all of them every frame, and for each one I check the distance to every other metaball and if they are close enough I need to merge them.
This is how I guess it could look, but I don't know how to properly remove the element from array and not break the loops.
for(var i = 0; i < points.length; i++) {
for(var j = 0; j < points.length ; j++) {
if(i != j) {
if(distance < 10) {
//remove one of the points using splice
}
}
}
}
Thanks for help.
First, start your inner loop at i + 1. You've already compared elements up to i, so there's no need to repeat, right? That let's you get rid of your if statement as well.
Then, when you splice, decrement j so as to not skip the next element.
for(var i = 0; i < points.length; i++) {
for(var j = i + 1; j < points.length ; j++) {
if (distance(i, j) < 10) {
points.splice(j--, 1);
}
}
}
Related
I am trying to create a sorting visualizer on Angular, and I decided to use the chart.js bar chart. I am trying to visualize bubble sort at the moment, and I would like to add a delay in every iteration of the inner loop. I am sure that you are familiar with the loop structure of bubble sort. I want to do the comparison, then call the draw function I made to draw the updated chart, and then after a 0.5 second delay, move onto the next iteration.
for (let i = 0; i < this.data.length; i++) {
for (let j = 0; j < this.data.length; j++) {
//comparison
this.draw();
// 0.5 SECOND DELAY
}
}
I'm sure there are better ways to manage the event loop in javascript than this, but i'll get you started:
jsfiddle: https://jsfiddle.net/zdfo5tce/
var data=[1,2,3,4,5]
var counter=0
let draw=(c) => document.body.innerHTML=c;
for (let i = 0; i < this.data.length; i++) {
for (let j = 0; j < this.data.length; j++) {
//comparison
setTimeout(draw.bind(this, counter), ++counter*500);
// 0.5 SECOND DELAY
}
}
this will delay each iteration by 500 ms
for (let i = 0; i < this.data.length; i++) {
for (let j = 0; j < this.data.length; j++) {
setTimeout(function(){
this.draw();
}, 500 *j);
}
}
I got the code below working, but when I try to add a Browser.msgBox() once there is a duplicate in the comparison, the code keeps running until it exceeds its time limit.
The idea is to notify the user that the item he/she is trying to add is duplicated and have the script stop running.
var duplicate = false;
for(var x = 0; x < data.length; x++) {
for(var j = 0; j < dataArquivoItens.length; j++){
if(data[x].join() == dataArquivoItens[j].join()){
duplicate = true;
break;
}
}
}
Thanks a lot!
You are only breaking out from the if statement, this is why your code keeps iterating
If you want to break from all nested loops/ statements - give them a name
Sample:
var duplicate = false;
loop1:
for(var x = 0; x < data.length; x++) {
loop2:
for(var j = 0; j < dataArquivoItens.length; j++){
if(data[x].join() == dataArquivoItens[j].join()){
duplicate = true;
Browser.msgBox("That's a duplicate");
break loop1;
}
}
}
I need to convert this nested loop into a single loop.
This is the loop with the scenario:
First incrementer is i which starts from 0 and should run till 10
Second incrementer is j which starts from where i left off + 1 and runs till 10
.
.
My Nested Loop
for (var i = 0; i < 10; i++) {
for (var j = i + 1; j < 10; j++) {
if (some_condition) {
do_sth()
}
}
}
My Attempt at conversion
var i = 0;
while (i < 10){
var j = i + 1;
if (j < 10) {
if (some_condition) {
do_sth()
}
j++;
}
i++;
}
Unfortunately, my attempt doesn't produce the expected results.
The second snippet does not give the output which the first snippet delivers.
Can anyone please suggest me what my mistake is or provide me a better solution to achieve my target?
Thanks!
Not sure it improves readability complexity, but the following should produce the same.
var i = 0, j = 1;
while (i < 9) {
console.log(i, j);
j += 1;
if (j >= 10) {i += 1; j = i + 1}
}
You need to update i inside else statement or use continue. And declare j outside of the while body.
But keep in mind that this neither change "the order of complexity" nor "optimise" your code.
var i = 0;
var j = 1;
while (i < 10) {
if (j < 10) {
if (true) {
console.log(i, j)
}
j++;
} else {
i++;
j = i + 1;
}
}
You could adjust the loop lenght of i and check if j is greater or equal than 9, then increment i and start with fresh j.
var i = 0,
j = 1;
while (i < 9) {
console.log(i, j);
// do you stuff
if (j >= 9) j = ++i;
j++;
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
the following code goes into infinite loop and a crash in the webpage I need to know what's wrong with it?
for (var i = 0; i < 2; i+1) {
for (var j = i; j < 8; j + 2) {
console.log(arr[j].Qu);
}
console.log(arr[i]);
}
i+1 doesn't update i's value, therefor, the i always has value 1, as it takes 0+1 in every run, thus never being > 2 and never ending
You need to change it with i++, like this
for (var i = 0; i < 2; i++) {
Also, as #Xufox points out, udpate your J loop with
for (var j = i; j < 8; j += 2) {
i+1 is not an assign operation, that's why you need to assign the value urself. i++ and j+=2 translate to
i = i+1;
j= j+2;
and the result of the righthand operation is self-assigned to the variable
Value is not assigned back to variable.
for (var i = 0; i < 2; i+=1) { // i++
for (var j = i; j < 8; j+=2) {
console.log(arr[j].Qu);
}
console.log(arr[i]);
}
i+1 doesn't modify i value.
You could write instead i++.
Similarly, j + 2 doesn't update j.
You should write j += 2.
Here is the corrected code :
for (var i = 0; i < 2; i++) {
for (var j = i; j < 8; j += 2) {
console.log(arr[j].Qu);
}
console.log(arr[i]);
}
for (var i = 0; i < 2; i+=1) {
for (var j = i; j < 8; j+= 2) {
console.log(arr[j]);
}
console.log(arr[i]);
}
I have a 3d array-DataSeriesToPlot in Javascript, what I want to do is all first half rows' elements value plus a value- scale, all remaining half rows'elements value minus the value-scale. The code is like the below showed,
for ( var i = 0; i < DataSeriesToPlot.length; i++) {
for ( var j = 0; j < DataSeriesToPlot[i].length; j++) {
if ((i >= 0) && (i < (DataSeriesToPlot.length / 2))) {
DataSeriesToPlot[i][j][1] = (parseFloat(DataSeriesToPlot[i][j][1]) + parseFloat(scale))
.toFixed(2);
} else {
DataSeriesToPlot[i][j][1] = (parseFloat(DataSeriesToPlot[i][j][1]) - parseFloat(scale))
.toFixed(2);
}
for ( var j = 0; j < DataSeriesToPlot.length; j++) {
console.log("aaaaa"+DataSeriesToPlot[j]);
}
But this ways seems incorrect, because the console output the original value of this 3d array, all values haven't been changed. Could you please help me figure out where the error is? Thanks!