function func(words) { // code ... } const words = ['Have', 'A', 'Good', 'Time', 'Have', 'Good'] func(words)
설명
Array.indexOf(), Array.filter()를 활용하여 배열 내 중복된 단어를 제거하는 함수를 작성해 주세요.결과
['Have', 'A', 'Good', 'Time']
const words = ['Have', 'A', 'Good', 'Time', 'Have', 'Good'];
function func(words) {
const wordsComp = [];
let filtered = words.filter(function func(word,index) {
if(words.indexOf(word,index+1) === -1) {
if(wordsComp.indexOf(word) === -1) return word;
} else {
wordsComp.push(word);
return word;
}
});
return filtered;
}
console.log(func(words));
처음 코드 짤 땐 그냥 배열 새로 안 만들고 indexOf의 리턴값이 -1이면 바로 리턴시켰음. 그런데 그러면 문제는 원하는 결과값은
['Have', 'A', 'Good', 'Time'] << 이건데
내 방식대로 하면
[ 'A', 'Time', 'Have', 'Good' ] << 이렇게 나옴.
당연히 인덱스 앞쪽에 있는 중복값이 먼저 제거되면서 이렇게 나오는 게 맞는데 어순이 3형식으로 구조상으로는 맞지만 해석상 이상하고 대소문자 용법도 어색하며 단수명사 뒤에 복수동사가 쓰인 것이 상당히 마음에 안들었음.. 그래서 문제가 원하는 결과값대로 출력하도록 고민함. 생각해낸 솔루션은 wordsComp 라는 새로운 배열을 생성하여 검사할 때 값이 중복인 요소들은 새로운 배열에 넣음. 요소들을 모두 리턴하되 대신 새로운 배열에 같은 값이 존재하는 인덱스들은 배제함. 그러면 아까와 반대로 앞에 있는 중복 요소들은 남지만 뒤에 있는 중복 요소들이 필터링됨.
const words = ['Have', 'A', 'Good', 'Time', 'Have', 'Good'];
function func(words) {
const result = words.filter((word, index) => {
return words.indexOf(word) === index
})
console.log(result)
}
func(words)
나름 짱구 좀 굴려서 답을 썼다고 생각했는데.. 모범 답안을 보고 아? 싶었다.
indexOf의 리턴값은 결국 인덱스이니까, 검사하는 요소의 indexOf 리턴값과 요소의 인덱스가 같다면 중복 요소가 없다고 판단할 수 있고, 다르다면 indexOf 리턴값이 -1이 나온 것이니 중복 요소가 있다고 판단하는 것이다.
메소드에 대한 정확한 이해가 있으면 이렇게 쉽게 활용해 풀 수 있는데 나는 단순히 '중복이면 리턴 값이 -1'이라는 것에만 집착해 풀었으니 훨씬 복잡하게 풀 수 밖에.
메소드를 이해하고 활용하자.
화살표 함수 익숙해질 것.