12.28 TIL

4290 단어 TILTIL

reduce 만들기

reduce를 사용해 본 적은 많지만 직접 reduce를 만들어 볼 생각은 하지 못했는데, 미션이 있어서 만들어봤다. 처음 생각으로는 클로저를 사용해 acc에 cur를 더해주는 식으로 해보려고 했는데, 굳이 클로저를 활용하지 않아도 반복문으로 충분히 가능했다.

const myReduce = (arr, callback, initialValue) => {
  let acc = initialValue ? initialValue : arr[0];
  if (initialValue) {
    arr.forEach((cur) => (acc = callback(acc, cur)));
  } else {
    for (let i = 1; i < arr.length; i++) {
      acc = callback(acc, arr[i]);
    }
  }

  return acc;
};

내가 만든 코드는 위와 같은데, 배열을 받아서 배열을 돌면서 callback함수를 호출해주는 방법을 사용했다.
initialValue가 있다면 배열의 처음부터 끝까지 돌고, initialValue가 없다면 배열의 첫 번째 요소를 initialValue로 사용해서 배열의 두 번째 요소부터 반복문을 돌게 했다.

위 코드에서 arr을 입력하지 않고, 메소드로써 동작하게 하기 위해서는 Array.prototype에 할당하면 되는데,

Array.prototype.myReduce = function (callback, initialValue) {
  let acc = initialValue ? initialValue : this[0];
  if (initialValue) {
    this.forEach((cur) => (acc = callback(acc, cur)));
  } else {
    for (let i = 1; i < this.length; i++) {
      acc = callback(acc, this[i]);
    }
  }

  return acc;
};

이렇게 Array.prototype에 할당하게 되면 우리가 사용하는 reduce와 같게 사용할 수 있게 된다.
이유는 this가 "." 앞에 있는 배열을 가리키기 때문이다.
하지만 여기에서 화살표 함수를 사용하게 되면 this가 undefined가 되어 오류가 발생하게 되는데, this를 설정해주기 위해 bind나 call을 사용해야 할 것 같지만 아직 방법을 찾지 못했다.

skeleton code, pseudo code

skeleton code 와 pseudo code에 대해 공부했는데, 구현해야 할 코드의 설계를 할 때 유용한 방법이라는 생각이 들었다.

skeleton code는 이름에서 느껴지듯이 전체를 볼 수 있도록 뼈대를 만드는 설계이다.
즉, 어떤 코드를 만들어야 할 때, 어디서부터 시작해야 할지 막막하다면 skeleton code를 사용해서 나아가면 된다.

예를 들어, 난 할 일 관리 프로그램을 만들고 있는데, 큰 뼈대를 생각해 보면
1. 할 일을 관리해 주는 클래스
2. 할 일을 보여주는 클래스
로 나누어서 생각해 볼 수 있다.

두 개의 큰 뼈대를 만든 후에 다시 작은 뼈대를 설계하면서 나아가면 된다.

1. 할 일 관리 클래스
- 할 일 입력
- 할 일 삭제
- 상태 업데이트 
- 태그 추가 
- 태그 삭제
- 이름 변경 

2. 할 일 보여주기 클래스
- 모든 할 일의 상태 보여주기
- 상태에 맞는 할 일 보여주기

이렇게 필요한 기능을 생각해서 설계를 한 뒤에 조금 더 자세하게 설명을 적는다.

1. 할 일 관리 클래스
- 할 일 입력 : 할 일을 추가할 수 있는데, name, tags, status를 입력받는다.
- 할 일 삭제 : 할 일의 이름을 입력해 삭제할 수 있다.
- 상태 업데이트 : 할 일의 상태를 업데이트 할 수 있으며, todo, doing, done의 3단계가 있다.
- 태그 추가 : 태그 명을 입력해 태그를 추가할 수 있다. 
- 태그 삭제 : 태그 명을 입력해 삭제할 수 있다.
- 이름 변경 : 할 일의 이름을 변경할 수 있다.

2. 할 일 보여주기 클래스
- 모든 할 일의 상태 보여주기 : all이 입력되었을 때, 모든 할 일 상태를 보여준다.
- 상태에 맞는 할 일 보여주기 : 특정한 상태가 입력되었을 때, 입력된 상태에 맞는 할 일을 모두 보여준다.

이런식으로 조금 더 자세하게 설명을 적으면 큰 틀을 미리 잡아놓고 코딩을 시작할 수 있게 된다.
이것은 메소드를 정의하는 것과 동일하다고 생각하면 될 것 같다.

더 나아가서, 할 일을 입력할 때 이미 존재하는 이름이라면 추가할 수 없어야 하고, id를 부여하는데 id가 중복되지는 않았는지 검사하는 메소드가 필요할 수 있다.

세부적인 기능을 추가적으로 작성해보면

// 할 일 관리 클래스
- 할 일의 이름 중복 확인 : 입력 받은 name이 todosList에 존재하는지 확인한다.
- id 부여 : id가 중복되지 않는지 확인 후에 id를 부여한다.
- 같은 상태로의 업데이트 확인 : 동일한 상태가 입력되었는지 확인한다.
- 할 일 목록 찾기 : 입력 받은 name을 바탕으로 목록에서 할 일을 찾는다.

이렇게 작성해볼 수 있다.
나는 항상 이렇게 메소드를 나눌 때마다 걱정이 되는 것이 있다. 그것은 할 일의 이름 중복을 확인하는 메소드나 id를 부여하는 메소드는 굳이 할 일 class에 속해 있을 필요가 없다고 생각이 되어서 util 함수로 만들어야 할까? 에 대한 것이다.

우선은 skeleton code를 연습하기 위한 것으로 위의 고민은 다음에 하고, 세부 메소드를 나누었으면 이제 구현할 일만 남았다.

구현하기 위해서는 위의 뼈대를 토대로 pseudo code를 사용하면 편리한데, pseudo code를 간략하게 설명하면 가짜 코드를 만드는 것이다.

내가 설계하려고 하는 코드의 가짜 코드를 미리 만들어놓는데, 한글로 만들기 때문에 이해하는 것에 많이 도움이 된다.

// 할 일 입력
f 할 일 입력 addTodo(todoName, tags, status){
  // 이름 중복 검사를 마친 후 이상이 없으면 id 부여, 이상이 있으면 error
  // id와 받은 매개변수를 바탕으로 todo obj 생성

  if(이름 중복 검사 메소드 호출(todoName) : 이름이 중복된다면){
    return alert('이름이 중복됩니다.');
  }
  const todoId = id 생성 메소드 호출;
  const 추가할 todo = {
      name : todoName,
      tags,
      status,
      id : todoId,
  }

  return todosList에 추가할 todo를 push
}

이렇게 한글로 설계할 코드에 대한 가짜 코드를 만들어서 이를 바탕으로 실제 코드를 구현하면 되는데, 어떤식으로 구현될 것인가에 대해서 확실하게 보이기 때문에 매우 유용한 것 같다는 생각이 들었다.

느낀점

pseudo code, skeleton code 둘 다 정해진 방식은 없다고 한다.
자신만의 방법으로 자신도 이해하기 쉽고, 다른 사람이 봤을 때도 이해하기 쉽도록 만드는 것이 중요하다고 생각이 든다.
또한, 나만의 언어로 작성한 코드이기 때문에 코드에 대한 이해도가 높아질 것이라는 생각이 들고, 이해가 높아진 만큼 코드 자체가 탄탄해질 것 같다는 생각이 들었다.

프로그래밍에서 중요한 것은 커뮤니케이션이라고 한다.
커뮤니케이션을 할 때 내 코드를 상대방에게 이해시키는 것이 중요하다고 생각하는데, 이 방법으로 계속 연습을 해나가면 커뮤니케이션은 문제가 없을 것 같다.

처음 해보는 것이라서 아직 미흡한 점이 많지만 연습하다보면 좋아질 것이라고 믿는다.

좋은 웹페이지 즐겨찾기