Is something wrong with my code? I was expecting my code:
years=new Array();
for (i = 0; i < 5; ++i) {
for (j = 1; j < 13; ++j) {
player.push(Math.round( nestedData[i].value[j] ))
}
years.push(player)
}
console.log(years)
to print something like:
[array[12],array[12],array[12],array[12]]
but the result that i get is:
[array[60],array[60],array[60],array[60]]
Create a new player array inside the first for loop. The problem with your code is that the values were being pushed into the same array instance.
var years = [];
for (i = 0; i < 5; ++i) {
var player = [];
for (j = 1; j < 13; ++j) {
player.push(Math.round( nestedData[i].value[j] ))
}
years.push(player)
}
console.log(years)
As an addition to the correct answer already, please use var to declare your variables:
for (var i=0; i < 5; ++i) {
var player = [];
for (var j = 1; j < 13; ++j) {
...
Otherwise, it will use i as a global variable, which could end poorly if you have two functions looping at the same time, e.g.:
function loopone() {
//wouldn't expect this to be an infinite loop eh?
for (i=0; i < 100; i++) {
looptwo();
}
}
function looptwo() {
for (i=0; i < 10; i++) {
}
}
Related
var s = '';
for (var i = 0; i < 5; i++) {
for (var j = 0; j < 10; j++) {
s += '*'
}
s += '\n';
console.log(s)
}
maybe you just know what makes the asterisks on this loop so much?
even though I only want to repeat it for 5 lines, but why are there so many results?
[1]: https://i.stack.imgur.com/7zzOu.png
Your code is producing the following result:
Because not resetting the var s inside the outter iteration.
Instead, you may do:
for (let i = 0; i < 5; i++) {
let s = '';
for (let j = 0; j < 10; j++) {
s += '*';
}
s += '\n';
console.log(s);
}
which will produce the expected result.
I'm trying to create a system of many objects that preform an action when they collide with each other, I'm using the P5.min.js library.
I've set up an array for the grid and an array for the objects, but I can't figure out the right way to go through each grid cell and check only the objects inside that cell before moving on to the next cell.
Here's what I've got so far
let molecules = [];
const numOfMolecules = 100;
let collisions = 0;
let check = 0;
let maxR = 10; //max molecule radius
let minR = 2; //min molecule radius
let numOfCol = 5;
let numOfRow = 5;
let CellW = 600/numOfCol; //gridWidth
let CellH = 600/numOfRow; //gridHeight
let remain = numOfMolecules;
let gridArray = [];
function setup() {
createCanvas(600, 600);
background(127);
for (let i = 0; i < numOfMolecules; i++) {
molecules.push(new Molecule());
}
}
function draw() {
background(127);
molecules.forEach(molecule => {
molecule.render();
molecule.checkEdges();
molecule.step();
});
drawGrid();
splitIntoGrid();
collision();
displayFR();
}
function drawGrid() {
for (i = 0; i < numOfRow+1; i++){
for (j = 0; j < numOfCol+1; j++){
noFill();
stroke(0);
rect(CellW*(j-1), CellH*(i-1), CellW, CellH);
}
}
}
function splitIntoGrid(){
for (let i = 0; i < numOfRow; i++){
for (let j = 0; j < numOfCol; j++){
tempArray = [];
molecules.forEach(molecule => {
if (molecule.position.x > (CellW*j) &&
molecule.position.x < (CellW*(j+1)) &&
molecule.position.y > (CellH*i) &&
molecule.position.y < (CellH*(i+1))) {
tempArray.push(molecule.id);
}
});
}
}
}
How I'm checking collision between all objects:
function collision() {
for (let i=0; i < molecules.length; i++){
for (let j=0; j < molecules.length; j++){
let diff = p5.Vector.sub(molecules[j].position, molecules[i].position);
check++;
if (i != j && diff.mag() <= molecules[j].radius + molecules[i].radius){
collisions++;
molecules[j].changeColor();
}
}
}
}
As far as I can see, I need to put these for loops inside another one going through each cell in the grid, but I don't know how to limit the search to which ever tempArray(s) the object is in
If this makes any sense, this is what I'm trying to do
function collision() {
for (let k = 0; k < gridArray.length; k++){
for (let i=0; i < gridArray.tempArray.length; i++){
for (let j=0; j < gridArray.tempArray.length; j++){
let diff = p5.Vector.sub(gridArray.tempArray[j].position, gridArray.tempArray.position);
check++;
if (i != j && diff.mag() <= gridArray.tempArray[j].radius + gridArray.tempArray[i].radius){
collisions++;
gridArray.tempArray[j].changeColor();
gridArray.tempArray[i].changeColor();
}
}
}
}
}
The grid cell is represented by an array of array gridArray. You need to have a collection of molecules for each grid cell. My recommendation would be to use Sets instead of an Array since the order is irrelevant. The idea is to be able to access the set of molecules on a given grid cell (i,j) with the syntax:
gridArray[i][j]
The following code will create an array of numOfRow arrays:
const numOfRow = 5;
const gridArray = (new Array(numOfRow)).fill([]);
gridArray with look like this:
[ [], [], [], [], [] ]
Inside splitIntoGrid you are checking which molecules are in which grid cells. This is good. However, for each grid cell, you are overwriting the global variable tempArray. Therefore, at the end of the function's execution, tempArray will only hold the molecules of the last grid cell, which isn't what you want. For a given grid cell, we will add the right molecules to a Set associated with this grid cell.
The Set data structure has an #add method which appends a new element to the set:
function splitIntoGrid() {
for (let i = 0; i < numOfRow; i++) {
for (let j = 0; j < numOfCol; j++) {
gridArray[i][j] = new Set();
molecules.forEach(molecule => {
if (molecule.position.x > (CellW*j)
&& molecule.position.x < (CellW*(j+1))
&& molecule.position.y > (CellH*i)
&& molecule.position.y < (CellH*(i+1))) {
gridArray[i][j].add(molecule);
}
});
}
}
}
Now you're ready to check for collisions on each grid cells. We will have a total of four loops inside one another. Two to navigate through the grid and two to compare the molecules that are contained inside each grid cell:
function collision() {
for (let i = 0; i < numOfRow; i++) {
for (let j = 0; j < numOfCol; j++) {
gridArray[i][j].forEach(moleculeA => {
gridArray[i][j].forEach(moleculeB => {
const diff = p5.Vector.sub(moleculeA.position, moleculeB.position);
if (moleculeA != moleculeB && diff.mag() <= moleculeA.radius + moleculeB.radius) {
collisions++;
moleculeA.changeColor();
moleculeB.changeColor();
}
});
});
}
}
}
In the above code, #forEach comes in handy.
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 implemented recursively search the adjacent faces using Half Edge data structure and color them accordingly. However, I can see the effect on the firefox but not on chrome. Does anyone have an idea? Help would be appreciated!
function neighbor(color_indices){
var color_indices_length = color_indices.length;
for (var i = 0; i < color_indices_length; i++) {
var adjacentFaces = heData.findAdjacentFacesToFace(color_indices[i]);
for (var k = 0; k < 3; k++){
if(color_indices.indexOf(adjacentFaces[k]) == -1) {
color_indices.push(adjacentFaces[k]);
}
}
}
}
function recursion(recursion_times, color_indices){
for (var z = 1; z <= recursion_times; z++){
neighbor(color_indices)
}
}
function red() {
gl_object.colorsNeedUpdate = true;
for(var j=0; j < red_indices.length; j++){
gl_object.children[0].geometry.faces[red_indices[j]].color = new THREE.Color(0xff0000);
}
}
function red_color() {
red_indices.push(selectedFaces[0].faceIndex);
recursion(11,red_indices);
red();
}
Also, I tried this implementation, too! but has the same effect (not working on my chrome)
//test
var adjacentFaces = [];
var temp = [];
temp[0] = heData.findAdjacentFacesToFace(color_indices[i])[0];
temp[1] = heData.findAdjacentFacesToFace(color_indices[i])[1];
temp[2] = heData.findAdjacentFacesToFace(color_indices[i])[2];
adjacentFaces.push(temp[0]);
adjacentFaces.push(temp[1]);
adjacentFaces.push(temp[2]);
it was the simple matter just change
for (var k = 0; k < 3; k++){
if(color_indices.indexOf(adjacentFaces[k]) == -1) {
color_indices.push(adjacentFaces[k]);
}
}
to
for (var k = 0; k < adjacentFaces.length; k++){
if(color_indices.indexOf(adjacentFaces[k]) == -1) {
color_indices.push(adjacentFaces[k]);
}
}
I try to create a 4-dimensional array. I fill it dynamically and use content of it in another function. But the content is empty. Is there error below code?
var datas = []; // day number of a week
for(var i = 0; i < 7; i++) {
var size = 24*60/timeInterval;
datas[i] = [];
for(var j = 0; j < size; j++) {
var size2 = allCoords.length / 2;
datas[i][j] = [];
for(var k = 0; k < size2; k++) {
datas[i][j][k] = [];
}
}
}
I test below example :
function foo1()
{
datas[0][0][0].push(10);
}
function foo2()
{
document.getElementByID('result').innerHTML = datas[0][0][0];
}
I see only ,,,,,,,.
I think the principal problem is that you're getting the element where you want to show your result badly using getElementByID instead of getElementById. Also make sure that your element has innerHTML property to write the result, or alternatively use value.
I write the follow example using <textArea id="result"></textArea> and generating a button which calls foo1();foo2(); onClick an it works for me.
In the sample I use an random value for timeInterval and allCoords.length.
Note also that you want a 4-dimensional array however you're creating a 3-dimensional.
var timeInterval = 60;
var allCoords = { length : 1};
var datas = []; // day number of a week
for(var i = 0; i < 7; i++) {
var size = 24*60/timeInterval;
datas[i] = [];
for(var j = 0; j < size; j++) {
var size2 = allCoords.length / 2;
datas[i][j] = [];
for(var k = 0; k < size2; k++) {
datas[i][j][k] = [];
}
}
}
function foo1()
{
datas[0][0][0].push(10);
}
function foo2()
{
document.getElementById('result').value = datas[0][0][0];
}
<textArea id="result"></textArea>
<input type="button" value="foo" onclick="foo1();foo2();"/>
Hope this helps,