문제: 배열을 입력받아 배열에서 가장 짧은 길이를 가진 문자열 요소를 리턴
입력: arr _ 임의의 요소가 담긴 배열
출력: string 타입을 리턴해야 합니다.
주의 사항
-
반복문(for, while) 사용은 금지됩니다.
-
같은 길이의 요소가 있다면 배열의 앞쪽에 있는 요소를 리턴해야 합니다.
-
배열에는 문자열 외에 다른 요소들이 있을 수 있습니다.
-
빈 배열을 입력받은 경우, 빈 문자열을 리턴해야 합니다.
-
주어진 배열에 문자열이 없는 경우, 빈 문자열을 리턴해야 합니다.
입출력 예시
let output = findShortestWord([4, 'two', 2, 'three']);
console.log(output); // --> 'two'
문제 풀이 설명
[4, 'two', 2, 'three']로 arr가 입력된 경우를 생각해 보자.
1. 먼저 문자열이 아닌 number type이나 다른 타입이 들어올 수 있다. 그런 경우 어떤 array 메소드를 사용해서 걸려주어야 할까?
2. 문자열만 담긴 새로운 배열안의 각 element의 문자열을 어떻게 길이를 비교할 수 있을까?
1번에 대한 질문은 filter를 사용하면 될 것이고
2번에 대한 질문은 reduce를 사용하면 될 것이다.
1. 입력받은 arr를 필터해서 새로운 문자열만 있는 변수에 담는다.
let stringArr = arr.filter(function(el){
return typeof el === 'string';
});//stringArr 에는 오직 문자열 타입만 담겨 있다.
2. 문자열만 있는 변수 stringArr안에 있는 문자열의 길이를 비교하기 위해 reduce를 사용한다.
이제 할 일은 문자열만 담긴 배열에서 문자열의 길이를 비교하는 것이다. 이때 reduce메소드를 활용하면 된다.
reduce는 숫자의 합만 구하는 것이 아닌, 배열의 배열를 flatten 하거나, 객체 인스턴스의 value 수 세기, 문자열이 큰 것과 작은 것의 비교 등에도 쓰인다. map, sort, some, every, find, includes도 다 reduce로 구현이 가능하다. type를 변환할 때도 reduce가 쓰인다.
return stringArr.reduce(function(acc, cur){
//이제 stringArr안에 있는 문자열의 길이를 if문으로 비교하면 된다.
if(acc.length <= cur.length) {//초기값이 없으면 acc가 초기값이 된다.
//['two', 'three']에서 acc는 'two'가 되고 cur는 'three'가 된다. 두개의 문자열을 비교해서 짧은 쪽을 리턴하면 된다.
return acc;
} return cur;
});
reduce에 초기값을 설정하지 않았기 때문에 acc가 초기값이 되고 cur가 다음값이 된다. 그래서 그 길이를 서로 비교할 수 있다. acc.length와 cur.length를 통해 길이를 비교한다. reduce를 통해 stringArr 안에 있는 모든 문자열을 서로 acc, cur를 비교하게 된다.
아래는 코드 풀이 전체이다.
function findShortestWord(arr) {
//[1. 빈 배열인 경우 빈 문자열을 리턴한다. ]
if(arr.length === 0) return '';
//[2. 문자열이 있는 경우 filter사용해서 문자열만 새로운 변수에 담는다 ]
//for, while 반복문을 사용하지 않고 배열 내장 메소드 중에서 for문을 대체할 것이 무엇이 있지? forEach()?
//2-1. 그것보다 먼저 입력받은 arr에서 오직 문자열만 필터해야 한다. filter 를 사용해야 한다.
let stringArr = arr.filter(function(el){
return typeof el === 'string';
});//stringArr 에는 오직 문자열 타입만 담겨 있다.
//2-2. 빈 배열은 아니지만 문자열이 하나도 없는 경우는 빈 문자열을 리턴한다.
if(stringArr.length === 0) return '';
//[3. reduce를 사용해서 문자열의 길이를 비교하여 가장 짧은 문자열을 리턴한다 ]
return stringArr.reduce(function(acc, cur){
//이제 stringArr안에 있는 문자열의 길이를 if문으로 비교하면 된다.
if(acc.length <= cur.length) {//초기값이 없으면 acc가 초기값이 된다.
//['two', 'three']에서 acc는 'two'가 되고 cur는 'three'가 된다. 두개의 문자열을 비교해서 짧은 쪽을 리턴하면 된다.
return acc;
} return cur;
});
}
이제 코드스테이츠의 최적화된 클린 코드 답안을 보고 내 것과 비교하도록 하자.
function findShortestWord(arr) {
const onlyStrings = arr.filter(function (el) {
return typeof el === 'string';
});
if (onlyStrings.length === 0) {
return '';
}
return onlyStrings.reduce(function (acc, cur) {
if (acc.length <= cur.length) {
return acc;
} else {
return cur;
}
});
}
거의 동일한데 한 가지만 다르다.
문제 조건에
-
빈 배열을 입력받은 경우, 빈 문자열을 리턴해야 합니다.
-
주어진 배열에 문자열이 없는 경우, 빈 문자열을 리턴해야 합니다.
이 두 조건을 보고 나는 각각
//[1. 빈 배열인 경우 빈 문자열을 리턴한다. ]
if(arr.length === 0) return '';
let stringArr = arr.filter(function(el){
return typeof el === 'string';
});//stringArr 에는 오직 문자열 타입만 담겨 있다.
//[2. 문자열이 하나도 없는 경우는 빈 문자열을 리턴한다. ]
if(stringArr.length === 0) return '';
1번과 2번 코드를 사용했다. 그렇지만 최적화 코드에서는 나의 1번 코드는 사용하지 않았다.
생각해 보면 사실 2번 코드만 사용해도 1번이 커버되기 때문이라는 것을 알 수 있다.
보다 효율적인 코딩은 불필요한 것을 줄이는 것이다.
이번 과제를 수행하면서 filter, reduce에 대해 좋은 복습의 시간을 가져서 좋았다.
'웹 개발 > javascript' 카테고리의 다른 글
| validation check(유효성 검사) 2 (0) | 2021.02.26 |
|---|---|
| validation check(유효성 검사) 1 (0) | 2021.02.26 |
| filter, map을 이용한 코드를 reduce로 refactoring하기 (0) | 2021.02.22 |
| underbar shuffle 메소드 (0) | 2021.02.22 |
| 재귀함수를 통해 Tower of Hanoi (하노이의 탑)문제 해결해보자 (0) | 2021.02.11 |
댓글