July 24th 2018
이번 포스팅에서는 세 개의 단어가 함수에 인자로 주어졌을 때 글자수가 가장 짧은 단어를 찾는 방법에 대해 정리해 보았습니다.
// 문제
var output = findMinLengthOfThreeWords('a', 'be', 'see');
// ---> 함수 호출 시 숫자 1이 나와야 함.
먼저 for문으로 구하는 법에 대해 정리해 보았습니다.
function findMinLengthOfThreeWords(word1, word2, word3) {
var newArr = [word1, word2, word3]; // 주어진 argument를 배열로 묶음.
var minlength = word1.length; // newArr 배열의 첫 요소 글자수로 변수를 초기 설정
for (var i = 0; i < newArr.length; i++) {
// newArr 배열의 요소 수 만큼 반복문 설정
if (newArr[i].length <= minlength) {
minlength = newArr[i].length;
} //현재 배열 요소의 글자수가 minlength보다 작거나 같으면 minlength를 대체함.
}
return minlength;
}
다음은 배열의 reduce() method를 사용해 해결하는 방법에 대해 정리해 보았습니다. reduce method는 각 배열의 요소마다 callback함수를 적용해 반환된 값(accumulator)을 다음 요소의 callback 함수에 적용하며, 최종적으로 하나의 도출된 값을 반환합니다.
Reduce Method 요약 - reduce는 배열 요소를 순차적으로 이동하며, 누적된 계산값과 함께 callback을 적용해 최종적으로 하나의 값을 도출합니다. - syntac: arr.reduce(callback [, intialValue]) - 배열의 모든 요소의 계산을 누적해 하나의 결과값을 도출할 때 용이함. - immutable
Callback 함수의 parameter
reduce() method의 callback 함수는 아래와 같이 네 개의 parameter를 취할 수 있습니다.
- accumulator
- reduce method의 initial value가 설정되어 있으면 accumulator는 initial value가 되고, currentValue는 배열의 첫 요소가 됩니다. 만약, initial value가 생략되었다면 accumulator는 배열의 첫 번째 값이 되고 current value는 배열의 두 번째 값이 됩니다.
currentIndex
- currentvalue
- currentIndex
- 배열 내 현재 처리되고 있는 요소의 index 값입니다. method 작동 시 초기값이 주어진 경우는 0이되고, 초기값이 생략된 경우 1이 됩니다.
- array
- reduce method가 작동하고 있는 배열.
function findMinLengthOfThreeWords(word1, word2, word3) {
var newArr = [word1, word2, word3];
var shortestWord = newArr.reduce(function(acc, cur) {
if (acc.length <= cur.length) {
return acc;
}
});
return shortestWord;
}
var output = findMinLengthOfThreeWords('a', 'be', 'see'); // --> 'a'의 글자 수 1이 나옴
저는 처음 reduce() method의 callback 함수 return 값으로 acc.length로 설정했다가 결과 값으로 undefined를 받았습니다.
이유는 callback함수에서 return값이 acc.length인 숫자가 되면, callback이 두번째 호출될 때 if 조건절에서 숫자.length <= cur.length를 비교하게 됩니다. 숫자에는 length 속성이 없기 때문에 if 조건절이 false가 되고, 두 번째 callback함수의 결과가 없는 undefined가 반환되었습니다.
실수한 부분인 두 번째 callback 실행 시 변수에 값을 대입해서 코드를 살펴보면,
function findMinLengthOfThreeWords(word1, word2, word3) {
var newArr = [word1, word2, word3];
var shortestWord = newArr.reduce(function(acc, cur) {
if(1.length <= 'see') { // if( undefined <= 'see')
return acc.length
}
});
return shortestWord;
};
위의 경우 두 번째 callback의 결과값이 없었기 때문에 최종적으로 undefined를 반환했습니다.
아래의 함수는 underscore.js 라이브러리의 uniq 함수와 동일한 기능을 구현한 것입니다. stackoverflow에 공유된 내용을, 참고차 정리해 봅니다.
참고로, 아래 함수는 배열에서 중복된 요소는 한 개씩만 남아있는 새로운 배열을 반환하는 함수입니다.
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniq = names.reduce(function(a, b) {
if(a.indexOf(b) < 0) {
a.push(b);
return a;
},[]});
console.log(uniq); // ["Mike", "Matt", "Nancy", "Adam", "Jenny", "Carl"]