요즘 인프런을 통해 알고리즘 강의를 수강 중인데 개인적으로 많은 도움을 받고 있다. 단순히 알고리즘 문제를 친숙하게 다가가기 위해 강의를 끊은것인데.. 의외로 실무에서도 크게 도움이 될 것 같아 이번 기회에 포스팅을 했다.
함수형 반복문
사실 지금까지 반복문을 사용하는 방법은 크게 신경쓰지 않았다. 보통 레거시 코드에서는 for
문을 많이 사용하는데(다른 언어에서도 많이 사용하고, 너무 친숙해졌다..) 이는 절대 낡거나 안좋은 코드라는 것은 절대 아니다!! 상황에 따라서 함수형으로 제공되는 반복문을 사용하는 경우가 효율적인 것도 있고 for를 사용하는 것이 더 효율적인 상황도 분명히 있다.
예를 들어 여러 중첩 반복을 하는 상황에서는 내부 변수를 다르게 사용하면서 가독성에 혼란을 줄 수 있다. 오히려 특정 상황에 반복문을 탈출할 때에는 for
를 사용하는 것이 더 효율적일 수 있다. 공식적으로는 forEach에는 breack
가 존재하지 않기 때문이다. (따로 상태 변수를 만들어 return 시키는 방법도 있지만, 배꼽이 더 커지는 상황이 될 수 있다..)
이런 경우에는 forEach
를 사용하면 확실히 코드도 덜 사용하게되고 눈에 보기도 더 쉬웠다.
forEach
for
와 용도는 완전히 동일하다. 단순히 순회 용도로 사용한다.
함수형 답게 콜백 함수를 받는데 두번째 인자로 내부에서 사용할 this
인자를 전달할 수 있다.
아래는 자바스크립트 기존 코드로 구현한 구현 소스와 메서드 사용법을 간략히 나타낸 것인데, 단순히 순회하는 용도로는 기존 for
보다 가독성이 좋다.
인자로 요소들을 간편하게 가져올 수 있어서 더 이상 배열 요소에 직접 접근 하지 않아도 된다. (단, 상황에 따라 break
를 해주는 로직이 필요하다면 기존 for문이 더 이롭다..)
//구현체
function forEach(predicate, thisArg) {
for (let i = 0; i < a.length; i++) {
predicate(a[i], i);
}
}
//예제
[1, 2, 3, 4, 5].forEach(
function (item, index) {
console.log(item, index, this); //여기서 가리키는 this는 두번째 인자
},
['a', 'b']
);
map
요소들을 이용해서 새로운 배열을 반환해주는 반복문이다.
중요한 것은 새로운 배열이 생성하기 때문에 배열과 동일한 길이를 가지고 있다. 따라서 반환 시 필터링 되는 요소가 있다면 undifined
를 반환하므로 이러한 용도로는 사용하는 것을 지양해야한다.
//구현체
function map(predicate, thisArg) {
let list = [];
for (let i = 0; i < a.length; i++) {
list.push(predicate(a[i], i)); //콜백 함수의 리턴 값을 다시 삽입
}
return list;
}
//예제
[1, 2, 3, 4, 5].map(
function (item, index) {
return item * index; //0, 2, 6, 12, 20
},
['a', 'b']
);
filter
map
과 마찬가지로 새로운 배열을 반환해주지만, 이름 그대로 필터링 될 수 있는 요소만을 반환한다.
//구현체
function filter(predicate, thisArg){
let list = [];
for(let i = 0; i < a.length; i++){
if(predicate(a[i], index){
list.push(predicate(a[i], index);
}
}
return list;
}
//예제
[1,2,3,4,5].filter(function(item, index){
return item % 2 === 1;
}); //1, 3, 5
reduce
배열을 반환하지 않고 내부적으로 계산된 값을 반환하는 함수이다.
대상 배열을 순회하면서 원소 값을 인자로 넘겨, 내부 계산식을 수행한 뒤 최종적으로 계산된 값을 반환한다.
두 번째 인자를 생략하면 0으로 초기화되고, 따로 초깃값을 넘길 수도 있다.
//구현체
function reduce(a, predicate, value) {
let result = val;
for (let i = 0; i < a.length; i++) {
result = predicate(result, a[i]);
}
return result;
}
//예제
[1, 2, 3, 4, 5].reduce(function (acc, item) {
return acc + item;
}, 0); //15
참고자료
- 자바스크립트 알고리즘 풀이 - 김태원 (인프런)