프런트엔드/리팩터링

레거시 코드 리팩터링 시리즈(5/5) 배열과 반복문

조드래곤나인 2023. 7. 17. 18:27

 

 

배열과 반복문

인덱스 반복문

for (let i = 0; i < 7; i++) 이런 형태의 인덱스 반복문을 많이 봤을 것이다. 이런 형태의 반복문은 바깥의 변수를 조작하는 부수효과를 만들게 된다.

const days = []
for (let i = 0; i < 7; i++) {
  days.push('Day ' + i)
}
// ['Day 0', 'Day 1', 'Day 2', 'Day 3', 'Day 4', 'Day 5', 'Day 6']
 

이러한 반복문은 range를 통해 작성이 가능하고 부수효과를 제거할 수 있다. 그리고 문자는 템플릿 리터럴로 정의하면 더 읽기 쉽게 정의할 수 있다.

const days = range(7).map(i => `Day ${i}`)
 
const range = length => Array.from({length}, (_, i) => i)
range(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 

 

배열의 요소 찾기

배열에 요소가 있는 지 찾는 코드를 indexOf를 통해 작성하는 코드 작성하기도 한다.

const hasItem = (arr, item) => arr.indexOf(item) >= 0
hasItem(['a', 'b', 'c'], 'a')
 

하지만 요소를 찾는 역할은 includes로 변경 가능하다.

const hasItem = (arr, item) => arr.includes(item)
hasItem(['a', 'b', 'c'], 'a')
 

 

깊은 배열 탐색하기

이런 형태의 데이터를 현실세계에서는 자주볼 수 있다.

const parents = [{
  value: '',
  children: [{value: ''}]
}]
 

중복된 이름인지 찾기 위한 작업을 할 때 이러한 코드를 볼 수 있다. for...of를 통해 배열을 순회한 뒤 값을 비교한다. 동일한 이름을 사용될 때 true을 반환하고 없을 때 false을 반환한다.

const isDupName = (parents, newName) => {
  for (const parent of parents) {
    if (parent.name === newName) {
      return true
    }
    for (const child of parent.children) {
      if (child.name === newName) {
        return true
      }
    }
  }
  return false
}
 

특정 값이 일치하는 지 찾는 동작은 some을 통해서 할 수 있다.

const isDupName = (parents, newName) => parents
  .some(({name, children}) => {
    if (name === newName) {
      return true
    }
    return children.some(({name}) => name === newName)
  })
 

 

 


 

 

728x90