简体   繁体   中英

How to know if selected cells is a rectangle in a CSS grid?

I have a div which displays a grid, like following:

render() {
    return (
            <div style={{display: "grid", gridTemplateColumns: "10px 10px 10px 10px", gridTemplateRows: "10px 10px 10px 10px"}}>
                {this.renderCells()}
            </div>
    );
}

In my renderCells() function I have:

renderCells = () => {
  let render = [];
  for(let i = 0; i < 16; i++)
    render.push(<div className="cell" key={i} onClick={() => this.clickElement(i)}>{i}</div>);
  return render;
}

It successfully generates 4x4 grid system with 0..15 numbers in it. On my clickElement() function I have:

const clickElement = (index) => {
    this.array.push(index);
}

I want to create a function to check if this.array has index numbers which can create a rectangle or a square.

Example:

Grid System
[0, 1, 2, 3]
[4, 5, 6, 7]
[8,9,10,11]
[12,13,14,15]

If user clicks 4, 5, 8 and 9 respectively, and after we run isRectangleorSquare() function it should return true, for 5, 6, 9 it should return false for example.

How can I write isRectangleorSquare() function?

This answer will imply that you have a javascript variable (in this case called 'matrix') that represent your css grid.

You could find the coordinates for the elements that have been selected and put them in a list (example for 4,5,8,9):

[
    [1 (vertical), 0 (horizontal)]
    [1, 1]
    [2, 0]
    [2, 9]
]

Than get the coords for the top-left corner and the bottom-right corner.

At this point loop through your original matrix and look if every element is in your list of selected elements.

Here it is the source code as an example:


let matrix = [
    [0, 1, 2, 3],
    [4, 5, 6, 7],
    [8, 9, 10,11],
    [12,13,14,15]
];

let selected = [4,5,8,9];

function isRectangle(selected) {
    let coords = [];

    // get the coords (could be optimised)

    for (let val of selected) {
        for (let row = 0; row < matrix.length; row++) {
            let idx = matrix[row].findIndex((x) => x == val);
            if (idx > -1) {
                coords.push([row, idx]);
            }
        }
    }

    // get the corners

    let mtop = Math.min(...coords.map((c) => c[0]));
    let mbottom = Math.max(...coords.map((c) => c[0]));
    let mleft = Math.min(...coords.map((c) => c[1]));
    let mright = Math.max(...coords.map((c) => c[1]));

    // check the values

    for (let i=mtop; i<=mbottom; i++) {
        for (let c=mleft; c<=mright; c++) {
            if (! selected.includes(matrix[i][c])) {
                return false;
            }
        }
    }

    return true;
}

isRectangle(selected);

This code could be improved in at least two ways:

  • Stop looking for the coordinates of a value as soon as you found them
  • Get the corners position while you're looking for the selected objects coordinates

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM