자바스크립트 코딩의 기술_반복문 작성의 기술_2

자바스크립트 2021. 5. 30. 18:42

(본 포스팅은 길벗의 '자바스크립트-코딩의 기술' 책을 공부하면서 작성되었습니다_내돈내산)

2021.05.30 - [자바스크립트] - 자바스크립트 코딩의 기술_반복문 작성의 기술_1

 

자바스크립트 코딩의 기술_반복문 작성의 기술_1

(본 포스팅은 길벗의 '자바스크립트-코딩의 기술' 책을 공부하면서 작성되었습니다_내돈내산) 1. 화살표 함수로 반복문을 단순하게 만들어라. 화살표 함수는 함수가 장황해지는 문제를 해결해서

pg-titannia.tistory.com

 

5. forEach( )로 동일한 동작을 적용하라.

  • 입력 배열을 전혀 변경하지 않고, 모든 항목에 동일한 동작을 수행한다.
  • 필요에 맞는 크기와 형태를 갖춘 배열을 얻은 후에 해당 데이터로 무언가를 해야할 때 흔히 사용한다.
  • forEach( )를 사용하는데 가장 큰이유는 체이닝과정에서 다른 배열 메서드와 결합이 가능하기 때문! 매번 배열 메서드의 결과를 저장할 필요 없이 동일한 배열에서 여러작업을 처리할 수 있게 된다.
const sailingClub = [
  'yi hong',
  'andy',
  'darcy',
  'jessi',
  'alex',
  'nathan',
];

// 일반 for 문을 사용한 경우
for (let i = 0; i < sailingClub.length; i++) {
  sendEmail(sailingClub[i]);
}

// forEach( )문을 사용하는 경우
sailingClub.forEach(member => sendEmail(member));
  • 일반 for문을 사용하는 경우도 사실 위의 코드보다 더 간단한 코드는 얻기가 힘들다.
  • forEach( )메서드의 가치는 코드를 단순하게 만드는데에 있는것이 아니라 예측가능하면서도 다른 배열 메서드와 같이 작동해 함께 연결할 수 있기 때문이다.
  • forEach( )에서 처리하는 동작은 모두 외부 함수에 영향을 주게 된다.
  • 부수효과를 주의하라고 하였지만, forEach( )의 경우 부수효과 없이는 아무 소용이 없다.

6. 체이닝으로 메서드를 연결하라.

  • 체이닝(chaining): 값을 다시 할당하지 않고 반환된 객체(또는 경우에 따라 원래 객체)에 메서드를 즉시 호출하는것
  • 체이닝은 여러개의 배열이 반환될 때, 배열 메서드를 연이어 호출할 수 있다는 것을 의미함.
const sailors = [
  {
    name: 'yi hong',
    active: true,
    email: 'yh@yhproductions.io',
  },
  {
    name: 'alex',
    active: true,
    email: '',
  },
  {
    name: 'nathan',
    active: false,
    email: '',
  },
];

// 1. 활동이 없는 회원 모두 제외
const active = sailors.filter(sailor => sailor.active);

  // [
  //   {
  //     name: 'yi hong',
  //     active: true,
  //     email: 'yh@yhproductions.io',
  //   },
  //   {
  //     name: 'alex',
  //     active: true,
  //     email: '',
  //   },
  // ];
  
// 2. 이메일 주소의 정규화
const emails = active.map(member => member.email || `${member.name}@wiscsail.io`);
// [ 'yh@yhproductions.io', 'alex@wiscsail.io' ]

// 3. 메일 보내기 함수 호출
emails.forEach(sailor => sendEmail(sailor));
  • 결과값을 매번 변수에 할당하였지만, 체이닝을 사용할 떄는 그럴 필요가 없다. 결과값에 직접 메서드를 호출해 변수에 할당하는 중간 단계를 제거할 수 있다.
// 메서드 체이닝을 이용한 중간단계의 간소화
sailors
  .filter(sailor => sailor.active)
  .map(sailor => sailor.email || `${sailor.name}@wiscsail.io`)
  .forEach(sailor => sendEmail(sailor))
  • 결과값으로 배열을 반환하는 메서드를 중간에 배치하고 배열을 반환하지 않는 forEach( ) 메서드를 가장 마지막에 배치하였다.
  • 메서드 체이닝의 유일한 단점은 새로운 메서드를 호출할때 마다 반환된 배열 전체를 다시 반복한다는 점에 있다. 
  • 꼭 마지막 문장까지 세미콜론이 없는 것을 확인해야 함.
  • 원하는 데이터를 조작함에 있어 순서를 철저히 고려하여 체이닝을 진행해야 한다.

7. reduce( )로 배열 데이터를 변환하라.

  • 배열을 이용해서 근본적으로 다른 새로운 데이터를 만들어야 할 경우. 예를 들어 특정항목의 수가 필요하거나, 배열을 객체처럼 다른 형태의 자료 구조로 변환해야 하는 경우 reduce( ) 메서드를 사용할 수 있음.
  • reduce( )메서드만의 가장 중요한 특징은 배열의 길이와 데이터 형태를 모두 또는 각각 변경할 수 있다는 것.
  • reduce( )메서드는 반드시 배열을 반환할 필요가 없다.
const callback = function (collectedValues, item) { 
    return [...collectedValues, item];
  };

const saying = ['veni', 'vedi', 'veci'];
const initialValue = [];
const copy = saying.reduce(callback, initialValue); 
  • - reduce( ) 메서드의 콜백함수에 두개의 인수를 전달한다(collectedValue, item). 두 개의 인수는 반환되는 항목(collectedValue)과 개별항목이다. 반환값은 콜백함수가 반환하는 값을 누적한 것이며,  반환값은 정수 뿐 아니라 세트같은 컬렉션도 될 수 있다. => function (누적값, 현재값)
  • - 마지막줄의 reduce( ) 메서드는 두가지 값, 즉 콜백함수와 기본값을 전달 받는다. 기본값은 선택적으로 넘겨줄 수 있지만, 대부분의 경우 작성한다. 기본값을 작성하면 반환값을 담을 수 있고, 다른 개발자에게 반환되는 값에 대한 단서를 제공할 수 있다.

const dogs = [
  {
    name: 'max',
    size: 'small',
    breed: 'boston terrier',
    color: 'black',
  },
  {
    name: 'don',
    size: 'large',
    breed: 'labrador',
    color: 'black',
  },
  {
    name: 'shadow',
    size: 'medium',
    breed: 'labrador',
    color: 'chocolate',
  },
];


// 원하는 고윳값이 색상일때, 객체를 순회하면 색상을 확인하고 고윳값을 저장하는 reduce( )를 구성해보자.
const colors = dogs.reduce((colors, dog) => { 
  if (colors.includes(dog.color)) { 
    return colors;
  }
  return [...colors, dog.color]; // 만일 여기서 누적값을 반환하지 않으면 값이 사라져버리게 됨.
}, []); 

// 초기값을 set 컬렉션으로 잡아두고 각 요소를 filter에 하나씩 누적해가는 과정을 나타냄.
const filters = dogs.reduce((filters, item) => {
  filters.breed.add(item.breed);
  filters.size.add(item.size);
  filters.color.add(item.color);
  return filters;
},
{
  breed: new Set(),
  size: new Set(),
  color: new Set(),
});
  • reduce( ) 메서드를 볼떄는 맨 뒷부분부터 보면 결과를 쉽게 알 수 있다. 기본값이 빈 배열이고 이를 colors라고 이름지어 그 빈 배열안에 계속해서 원본배열에 있는 dog.colors가 누적되도록 설계하였음.

8. for ...in 문과 for ...of 문으로 반복문을 정리하라.

- for ...of 문 -

  • for...of 문은 색인(인덱스값)을 반복하지 않는다.
  • for...of 문은 색인 대신 컬렉션은 멤버를 직접 순회한다.
  • 반복문 매개변수에서 개별 항목의 이름을 선언하고 이것을 반복문 내부에서 사용한다.
  • for...of 문을 사용하는 경우 특수한 객체를 배열로 변환하는 대신, for문과 동일한 개념을 사용하면서 색인에 대한 참조를 제거할 수 있다.
  • for문은 무엇이든 할 수 있지만, 반복문으로 무엇이든 할 수 있기 때문에 예측 가능성이 줄어드는 문제가 있다. 부수효과를 피하려면 문법이상의 규칙이 필요하게 된다.
  • 배열 메서드가 명확하고 적합할때는 for문을 이용하기 보다는 배열 메서드를 우선적으로 사용해야 한다.
for (const firm of firms) {
    const [id, name] = firm;
    if (!isAvailable(id)) {
      return `${name} is not available`;
    }
  }
  return 'All firms are available';

 

- for ...in 문 -

  • for ...in 문은 for...of문과 매우 유사하지만 객체의 속성을 순회하게 된다.
  • for ...in 문을 사용할 때는 각 항목을 한 번에 하나씩 받는다. 
  • 가급적 변수는 const로 선언해서 반복문의 내부에서 사용하게 된다.
const firms = {
  '10': 'Ivie Group',
  '23': 'Soundscaping Source',
  '31': 'Big 6',
};

 for (const id in firms) {
    if (!isAvailable(parseInt(id, 10))) {
      return `${firms[id]} is not available`;
    }
  }
  return 'All firms are available';
  • 키-값 쌍이 아니라 속성을 가져오기 때문에 이름과 값을 따로 추출할 필요가 없어진다. 
  • 값이 필요할때마다 배열 표기법으로 개별 항목의 값을 가져올 수 있다. 
  • 절대 객체를 순회하며 객체를 조작하지 않도록 한다. 
admin