Home > Software design >  How can I iterate though grid cells as a 2d array Javascript
How can I iterate though grid cells as a 2d array Javascript

Time:08-30

enter image description here

Now, you can use your snake coordinates, say [3,4], the div id will be 3_4, so you can simply do

const snake_element = document.getElementById(snake_coordinate[0] "_" snake_coordinate[1])
// apply your styles here

Also, if you are unable to use ids for some reason, you can add a CSS class in the same way

// in the loop
...
item.className=row "_" col;
grid.append(item);
...

// to access the element
const snake_element = document.getElementsByClassName(snake_coordinate[0] "_" snake_coordinate[1])[0]

CodePudding user response:

Basically, you trying to draw in 2d space. 1-dimensional array isn't a good solution for such task. It's better to use a 2d matrix to store your divs.

const grid = [];

// Assume it's 5x5 field
const xLength = 5
const yLength = 5;

for(let i = 0; i < xLength; i  ){
    grid.push([]);

    for(let j = 0; j < yLength; j  ){
        const item = document.createElement("div");
        grid[i].push(item);
    }
}

So now you can easily access each element by index.

const snake = [
    [2, 2],
    [3, 2],
    [4, 2]
];

snake.forEach(([x, y]) => {
    grid[x][y].classList.add("my-class");
});

But it'll work only if your grid has fixed dimensions.

CodePudding user response:

Calculate the position of the snake-part from it's row/column, and use :nth-child in a selector to target that box in the grid with querySelector.

Note: to be extra-cautious maybe check that pos doesn't exceed your grid bounds, and maybe log an error if it does.

const grid = document.querySelector('.grid');

const snake = [[2,2],[3,2],[4,2]];

// Create the grid adding classes to the boxes
// so they can intitially be seen
for (let i = 0; i < 25; i  ) {
  const box = document.createElement('div');
  box.classList.add('box');
  grid.append(box);
}

// Using the row/column from the snake-part array
// calculate its position in the grid
function getPosition([ row, column ]) {
  return (row * 5)   (column   1);
}

// For each snake-part array get the position,
// create a selector using `nth-child`,
// find that box in the grid, and add a new class to it
for (let i = 0; i < snake.length; i  ) {
  const pos = getPosition(snake[i]);
  const selector = `.box:nth-child(${pos})`;
  const box = grid.querySelector(selector);
  box.classList.add('snake');  
}
.grid { display: grid; grid-template-columns: repeat(5, 30px); gap: 2px; }
.box { width: 30px; height: 30px; background-color: #efefef;}
.snake { background-color: lightgreen; }
<div ></div>

Additional documentation

CodePudding user response:

you can do it this way,

const grid = document.querySelector(".grid");

for (let i = 0; i < 25; i  ) {
  var item = document.createElement("div");

  // save grid coordinates in the div element
  // e.g. <div data-x="0" data-y="0"></div>

  // get x coords 24 / 5 => Math.floor(4.8) => 4
  const x = Math.floor(i / 5);
  // get y coords e.g. 24 % 5 = 4
  const y = i % 5;

  item.dataset.x = x;
  item.dataset.y = y;

  // this is just to display coordinates.
  item.textContent = `(${x}, ${y})`; 
  // 

  grid.append(item);
}

// snake coords [x, y]

let snake = [
  [2, 2],
  [3, 2],
  [4, 2]
];

// [x, y] - this is array destructing is action.
for (let [x, y] of snake) {
  // find the corosponding div element.
  const item = grid.querySelector(`[data-x="${x}"][data-y="${y}"]`);
  item.style.background = "green";
}
.grid {
  display: grid;
  grid-template-columns: repeat(5, 40px);
  grid-template-rows: repeat(5, 40px);
}

.grid > div {
  border: 1px solid #000;
}
<div ></div>

  • Related