Finding neighbours in a two-dimensional array

后端 未结 20 1119
忘了有多久
忘了有多久 2020-11-30 02:02

Is there an easy way of finding the neighbours (that is, the eight elements around an element) of an element in a two-dimensional array? Short of just subtracting and adding

相关标签:
20条回答
  • 2020-11-30 02:21

    This was really helpful to me in a recent project, so here's @Seb 's pseudo-code implementation in swift. This is assuming that the two-dimensional array is square:

    func adjacentIndexPaths(to indexPath: IndexPath) -> [IndexPath] {
    var neighboringSquareIndexes: [IndexPath] = []
    
    // gridSquareCount is the size of the 2D array. For example, in an 8 x 8 [[Array]], gridSquareCount is 8
    let maxIndex = gridSquareCount - 1
    var neighborRowIndex = max(0, indexPath.section - 1)
    var neighborColumnIndex = max(0, indexPath.row - 1)
    
    while neighborRowIndex <= min(indexPath.section + 1, maxIndex) {
        while neighborColumnIndex <= min(indexPath.row + 1, maxIndex) {
            if neighborRowIndex != indexPath.section || neighborColumnIndex != indexPath.row {
                neighboringSquareIndexes.append(IndexPath(row: neighborColumnIndex, section: neighborRowIndex))
            }
            neighborColumnIndex += 1
        }
        neighborRowIndex += 1
        neighborColumnIndex = max(0, indexPath.row - 1)
    }
    
    return neighboringSquareIndexes }
    
    0 讨论(0)
  • 2020-11-30 02:23

    In javascript

        let arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    
            function getNeighborsNumbersAtIthJth(i, j) {
                let allPosibleIndexes = [
                    [i - 1, j],
                    [i, j - 1],
                    [i - 1, j - 1],
                    [i + 1, j],
                    [i, j + 1],
                    [i + 1, j + 1],
                    [i + 1, j - 1],
                    [i - 1, j + 1]
                ];
                let allPosibleValues = []
                allPosibleIndexes.forEach(([i, j]) => {
                    try {
                        allPosibleValues.push(arr[i][j])
                    } catch (err) {
    
                    }
                })
                return allPosibleValues.filter(v => v != undefined);
            }
            console.log(getNeighborsNumbersAtIthJth(1, 1));//[2, 4, 1, 8, 6, 9, 7, 3]
            console.log(getNeighborsNumbersAtIthJth(0, 1));//[1, 5, 3, 6, 4]
            console.log(getNeighborsNumbersAtIthJth(0, 0));//[4, 2, 5]
    
    0 讨论(0)
  • 2020-11-30 02:23
    // My approach in JS
    
    let size = 10
    //or some arbitrary number for the size of your grid.
    
    const neighbors = [
    
    [-1, -1], 
    [-1, 0], 
    [-1, 1], 
    [0, -1], 
    [0, 1], 
    [1, -1], 
    [1, 0], 
    [1, 1]
    
    ]
    
    for (let i = 0; i < size; i++) {
        for (let j = 0; j < size; j++) {
            neighbors.forEach(([x, y]) => {
                const newI = i + x;
                const newJ = j + y;
    
                if (
                    newI >= 0 && 
                    newI < size && 
                    newJ >= 0 && 
                    newJ < size
                   ) {
                    // you can access your grid neighbors here ----> grid[newI][newJ];
                  }
        ```
    
    I've found this approach helpful because it defines all of the array coordinates as transformations of the existing i and j indexes in your for loops.
    
    0 讨论(0)
  • 2020-11-30 02:24

    an alternative to @SebaGR, if your language supports this:

    var deltas = { {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1},
                   {x=-1, y=0},               {x=1, y=0},
                   {x=-1, y=1},  {x=0, y=1},  {x=1, y=1} };
    foreach (var delta in deltas)
    {
        if (x+delta.x < 0 || x + delta.x >= array.GetLength(0) ||
            y+delta.y < 0 || y + delta.y >= array.GetLength(1))
            continue;
    
        Console.WriteLine("{0}", array[x + delta.x, y + delta.y]);
    }
    

    Slight advantage in readability, possible performance if you can statically allocate the deltas.

    0 讨论(0)
  • 2020-11-30 02:24

    although nested for loops in list comprehensions is a bit ugly this is shorter:

    def neighbours(m, i, j):
        return [m[x][y] for x in [i-1,i,i+1] for y in [j-1,j,j+1] if x in range(0,len(m)) and y in range(0,len(m[x])) and (x,y) != (i,j)]
    
    0 讨论(0)
  • 2020-11-30 02:24

    I use a directions array and run a loop to get appropriate directions. Something like this (code is in JS)

    function getAdjacent(matrix, i, j, k) {
      const directions = [
        [i - 1, j - 1],
        [i - 1, j],
        [i - 1, j + 1],
        [i, j - 1],
        [i, j + 1],
        [i + 1, j - 1],
        [i + 1, j],
        [i + 1, j + 1],
      ];
      const [row, col] = directions[k];
      // Check for last rows and columns
      if (row < 0 || row >= matrix.length || col < 0 || col >= matrix[i].length) {
        return undefined;
      }
      return matrix[row][col];
    }
    
    function run(){
      const hello = 'hello';
      const matrix = [
        [1, 2, 1],
        [2, 1, 1],
        [1, 1, 1]
      ];
    
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          let sum = 0;
          for (let k = 0; k < 8; k++) {
            const res = getAdjacent(matrix, i, j, k);
            console.log(i, j, k, res); // Do whatever you want here
          }
        }
      }
    }
    
    run();

    0 讨论(0)
提交回复
热议问题