Remove duplicate words<7 kyu>

jjanmo·2020년 2월 6일
0

Codewars에서 뒹굴기

목록 보기
28/32

문제링크

문제

오늘 푼 문제는 주어진 문자열에서 중복되는 단어를 제거하는 문제이다.
예를 보면 쉽게 이해 할 수 있다.

Input:

'alpha beta beta gamma gamma gamma delta alpha beta beta gamma gamma gamma delta'

Output:

'alpha beta gamma delta'

문제접근

  function removeDuplicateWords (s) {
    const result = [];
    s.split(' ').forEach(ele=>{
      if(result.indexOf(ele) === -1) result.push(ele);
    });
    return result.join(' ');
  }

내가 문제를 푼 방식은 위와 같다. 문자열을 배열로 바꾼 뒤 그 배열을 순회하면서 중복되지 않는 값만 골라서 result라는 배열에 넣어준다. 첫번째 요소는 result가 빈 배열이기 때문에 무조건 들어가게 된다. 그 뒤로는 result 배열의 요소를 체크하게 된다.

Best Solution

  • 첫번째 풀이
1  function removeDuplicateWords (s) {
2    return s.split(' ').filter((n, i, s) => {
3      return s.indexOf(n) === i;
4    }).join(' ');
5  }

이 풀이가 내가 생각했던 방식이다. 메소드체인을 이용한 한 줄 풀이! (정확히는 끊기지않는 풀이??가 맞는듯) 그런데 3번라인에서 'indexOf()를 할 배열을 어떻게 선택해야하지?' 라는 고민을 해결하지 못했다. 단순하게 filter()의 parameter에는 filter() 하는 해당 배열(여기선 s)을 parameter를 넣을 수 있다는 것을 잊고 있었다. 저런 식으로 쉽게 해결되는 것을...😭 콜백함수의 element와 index만 사용을 하다보니;;

  • 두번째 풀이
const removeDuplicateWords = s => [...new Set(s.split(' '))].join(' ');

진짜 한 줄 풀이 등장이요!!
Set객체는 ES6에서 새롭게 등장한 컬렉션으로 중복되는 값을 포함 하지 않는다. 중복되는 값을 집어 넣어주면 알아서 제거된다. 그렇기 때문에 문자열 배열을 요소별로 하나씩 넣어주었을 때, 알아서 제거되서 유일한 요소만 남는 Set객체가 된다. 그것을 다시 배열로 바꾼 뒤 join()을 이용해서 합쳐주면 중복되지 않는 단어로 구성된 문자열이 만들어진다.

Set에 대해서

Set은 ES6에서 새롭게 등장한 객체이다. 중복되는 값을 갖지 않는 리스트이다. 즉 Set 내의 값은 한 번만 나타날 수 있다.(유일한 값이 된다) Set의 값이 될 수 있는 것들은 원시타입(strings, integers..)뿐만 아니라 객체리터럴이나 배열도 가능하다.

  • Set 생성
const foo = new Set(); //Set {}
const bar = new Set([1,2,4,2,5]); // Set {1,2,4,5}

new Set( [it] ) : Set객체를 생성하는 방법이다. it에 해당하는 것은 iterable object이다. 만약 it을 넣지 않는다면 빈 Set객체가 생성된다.

Set내의 값은 유일해야 한다. 그렇기 때문에 반복된 값이 넘겨지면 알아서 제거하고 유일한 값들만 남겨진다. Set내에 값을 저장하는 순서대로 저장된다. 즉 저장한 순서대로 순회하게 된다.

  • add(), size, has(), forEach(), delete(), clear()
let animals = new Set();

animals.add('🐷');
animals.add('🐼');
animals.add('🐢');
animals.add('🐿');
console.log(animals.size); // 4
animals.add('🐼');
console.log(animals.size); // 4

console.log(animals.has('🐷')); // true
animals.delete('🐷');
console.log(animals.has('🐷')); // false

animals.forEach(animal => {
  console.log(`Hey ${animal}!`);
});

// Hey 🐼!
// Hey 🐢!
// Hey 🐿!

animals.clear();
console.log(animals.size); // 0

Set.add(value) : Set객체 내에 새로운 요소를 추가한다. 중복되는 요소라면 추가되지 않는다.
Set.size : Set객체 내 값의 개수를 반환한다.
Set.has(value) : Set객체 내에 주어진 값을 갖는 요소가 있는지를 체크한다. 있다면 true를, 없다면 false를 반환한다.
Set.delete(value) : Set객체 내의 해당 요소를 제거한다.
Set.forEach() : forEach()는 배열의 메소드이지만 Set에서도 제공된다. Set객체를 순회한다.
clear() : Set객체 내의 모든 원소를 제거한다.

  • 서로 다른 타입을 Set에 추가해주는 경우
let myAnimals = new Set(['🐷', '🐢', '🐷', '🐷']);

myAnimals.add(['🐨', '🐑']);
myAnimals.add({ name: 'Rud', type: '🐢' });
console.log(myAnimals.size); // 4

myAnimals.forEach(animal => {
  console.log(animal);
});


// 🐷
// 🐢
// ["🐨", "🐑"]
// Object { name: "Rud", type: "🐢" }

중복된 🐷 이모지는 알아서 제거된다. 또한 이어서 저장된 배열과 객체가 순서대도 추가 된다. Set객체를 찍어보면 추가된 순서대로 출력됨을 알 수 있다.

사용된 예시는 밑에 참고 사이트(Introduction to Sets in JavaScript)에서 사용된 예시입니다.

결론

알고만 있는 것은 모르는 것과 같다. 지속적으로 사용해봐야 한다.

참고

Introduction to Sets in JavaScript

Set MDN

profile
눈길을 걸어갈 때 어지럽게 걷지 말기를.

0개의 댓글