2D 배열에서 요소의 좌표 찾기

그녀latest newsletter에서 보낸 코딩 챌린지를 진행하면서 2차원 숫자 배열에서 특정 숫자의 좌표를 찾아야 했습니다. 이렇게 하는 빠른 방법이 있습니다!

루프를 사용하여 좌표 찾기



3x3 숫자 배열이 있고 숫자 '5'의 위치를 ​​찾고 싶다고 가정해 봅시다. 여기서 xy 축을 임의로 지정했습니다.

const grid = [
---> y
|  [8,6,7],
|  [5,3,0],
v  [9,1,2]
x
]


간단한 접근 방식일 수 있지만 배열을 반복하는 것은 대상 요소를 찾는 간단한 방법입니다. 아래 기능을 확인하십시오.

const find2dCoordinates = <T>(
  grid: T[][],
  target: T
): {x: number, y: number} => {
  let coords = {x: -1, y: -1}
  grid.every((row, i) => row.every((item, j) => {
    if (item === target) {
      coords = {x: i, y: j}
      return false
    }
    return true
  }))
  return coords
}


먼저 일련의 좌표를 정의합니다: let coords = {x: -1, y: -1} ; 우리는 배열에 음수 좌표가 없다는 것을 알고 있기 때문에 반환된 객체에 음수 값이 있는 경우 오류가 발생했음을 알 수 있습니다.

다음으로 각 행의 각 항목을 반복합니다. 인덱스와 항목 자체를 원하기 때문에 .every() 루프 대신 for...of 함수를 사용합니다. 그런 다음 각 항목이 목표와 동일한지 확인합니다. 숫자 대신 객체 배열이 있는 경우 여기에서 다른 동등성 검사를 사용하고 싶을 것입니다.

이제 일치 항목을 찾으면 coords 변수에 좌표를 저장합니다. 하지만 약간의 문제가 있습니다! 우리는 for...of 루프를 사용하지 않기 때문에 break를 사용하여 루프에서 조기에 벗어날 수 없습니다. 😕 걱정하지 마세요. 우리가 이것을 계획했기 때문입니다 😎 .every() 대신 .forEach()를 사용하면 탈출구가 생깁니다.

.every() 메서드는 함수를 인수로 받아들이고 배열의 각 항목에 대해 해당 함수를 실행합니다. 이 함수는 true 또는 false를 반환해야 합니다. every() 함수가 배열의 모든 값에 대해 true를 다시 받으면 true를 반환합니다. 그러나 실패한 항목을 찾으면 false 를 반환합니다.

우리의 경우에는 true가 계속 찾도록 대상과 일치하지 않는 각 항목에 대해 every()를 반환합니다. 목표를 찾으면 false 를 반환합니다. 그러면 every() 가 일찍 튀어나오고 다른 .every() 함수에도 거품이 생깁니다. 성공!

평평한 배열은 어떻습니까?



경우에 따라 1차원으로 병합된 2차원 배열이 있을 수 있습니다. 이전에 PNG 이미지로 작업한 적이 있다면 픽셀 정보가 저장되는 방식입니다. 따라서 이전의 그리드는 [8,6,7,5,3,0,9,1,2] 가 됩니다. 이제 좌표를 어떻게 찾을 수 있습니까?

먼저, 우리가 찾고 있는 숫자의 인덱스를 찾아봅시다. 그런 다음 각 행의 원래 길이를 알면 좌표를 계산할 수 있습니다!

export const find2dCoordinatesFlattened = <T>(
  grid: T[],
  target: T,
  rowLength: number
): {x: number, y: number} => {
  const position = grid.findIndex(item => item === target)
  return {
    x: Math.floor(position / rowLength),
    y: position % rowLength
  }
}


먼저 .findIndex() 함수를 사용하여 1차원 배열에서 대상 항목의 인덱스를 찾습니다. 그런 다음 두 가지 트릭을 사용하여 x 및 y 좌표를 찾습니다. 찾은 인덱스를 원래 행 길이로 나누고 내림하면 항목이 속한 행을 찾을 수 있습니다. 그러면 행 길이가 있는 인덱스에 모듈로 연산자를 사용하면 어느 열에 속하는지 알 수 있습니다.

마지막 생각들



이것은 재미있는 작은 프로젝트였으며, 서두에서 언급한 newsletter의 퍼즐을 한 번 시도해 보는 것이 좋습니다!

또한 배열을 직접 평면화하고 두 번째 방법을 사용하는 것이 루프의 첫 번째 방법보다 빠를지 스스로에게 물었을 수도 있습니다. 두 방법을 비교한 이 벤치마크 결과를 확인하십시오.

먼저 아주 작은 2x3 배열에서 실행했습니다.


꽤 비슷한 점수! 하지만 50x10 배열에 대해 실행했습니다.


Yikes 😬 직접 평평하게 만드는 것은 뒤쳐져 있습니다. 그러나 루프가 결과를 찾으면 바로 들어가고 일찍 나올 수 있는 반면 전체 배열을 먼저 조작하여 평면화해야 하므로 이는 의미가 있습니다.

좋은 웹페이지 즐겨찾기