프로그래머스 Lv.1 신고 결과 받기, Object 대신 Map 활용하기, Set으로 배열 중복값 제거하기

이은지·2022년 5월 31일
0

코딩 테스트

목록 보기
4/10
post-thumbnail

처음으로 프로그래머스에서 코테 문제를 풀었다 👏🏻🏻🏻
보고 싶은 코테가 JS로만 시험을 볼 수 있대서 프로그래머스에서는 JS로 풀 예정
시작하자마자 킹이썬이 보고싶었는데 모범 풀이 보니 내가 JS를 10분의 1도 활용 못하는 것 같기두.

https://programmers.co.kr/learn/courses/30/lessons/92334

단순한 구현 문제였는데 자바스크립트로 문제푸는 게 익숙치 않아서 헤맸다.
객체를 활용해서 어떻게 풀긴 했지만 매우 찜찜해서 모범 답안 보고 공부했다👊🏻.
자바스크립트도 잘만 쓰면 나름의 재미가 있을 것 같다는 생각.
프로그래머스 모범 답안 볼 수 있는 기능 조아

😒 기존 풀이

function solution(id_list, report, k) {
    const users = {}
    id_list.map((user, idx) => {
        users[user] = {idx, report:[], reported:[]};
    })
    report.map((item) => {
        let [reporter, reported] = item.split(" ");
        if(!users[reporter].report.includes(reported)){
            users[reporter].report.push(reported);
        }
        if(!users[reported].reported.includes(reporter)){
            users[reported].reported.push(reporter);
        }
    })

    var answer = new Array(id_list.length).fill(0);

    for(let key in users){
        if(users[key].reported.length>=k){
            users[key].reported.map((reporter) => {
                let idx = users[reporter].idx;
                answer[idx]+=1;                
            })
        }
    }

    return answer;
}

😉 바뀐 풀이

function solution(id_list, report, k) {
    const reports = [...new Set(report)].map((item)=>{return item.split(' ')});
    const cnts = new Map();
    reports.map((rep)=> {
        cnts.set(rep[1], cnts.get(rep[1])+1||1);
    })
    const mailCnt = new Map();
    for(report of reports){
        const good = report[0];
        const bad = report[1];
        if(cnts.get(bad)>=k){
            mailCnt.set(good, mailCnt.get(good)+1||1);
        }
    }
    const answer = [];
    id_list.map((id)=> {
        answer.push(mailCnt.get(id)||0);
    })
    return answer;
}

🦋 개선 포인트

✅ Set 사용해 중복값 제거하기

기존 코드에선 새로운 신고자를 추가할 때마다 includes로 기존 신고자 배열을 순회 탐색하여 중복 신고 여부를 확인했다. 새로운 코드에서는 애초에 시작할 때 Set을 사용해 report 배열에 존재하는 중복값을 없앴다.

Set 생성자의 인자로 배열을 넘기면 배열에서 중복값이 제거된 집합이 만들어진다.
이를 다시 spread 연산으로 복사해 []에 넣으면 해당 집합과 똑같은 요소를 가지는 배열을 만들 수 있다.
[...new Set(arr)]

✅ Object 대신 Map 사용하기

제발 한국인이라면 자바스크립트 Object를 Map 처럼 사용하지 맙시다.
아주 좋은 글을 발견 👍🏻

Map을 처음 접해봤다.

Map이란?
: key-value 형태로 정보를 저장하고 싶을 때 사용할 수 있는 자료구조

Map - JavaScript | MDN

object와의 차이점

  • key로 여러 가지 type을 사용할 수 있다.
    object의 경우 string type만 key로 사용할 수 있다.
    key를 stringify할 필요가 없다.
  • O(1)으로 길이를 구할 수 있다.
    object의 경우 객체의 key를 받아와 그 길이를 구해야 하기 때문에 O(N)이 소요된다.
    Object.keys(objname).length)
  • 추가한 순서에 따른 순번이 보장된다. → python dictionary 사용할 때 했던 고민 해결
  • 그 자체로 iterable 하다. Object의 경우 key를 사용해 iterate한다.
    // Map
    
    for (let [key,val] of map) {
    	console.log(`${key} = ${value}`);
    }
    
    // Object
    for (let key of Object.keys(objname)){
    	console.log(`${key} =${objname[key]}`);
    }

파이썬에서 쓰던 딕셔너리와 유사한 느낌. 앞으로 종종 사용해 봐야겠다.
string이 아닌 다른 타입을 key로 사용할 수 있단 점이 매우 파격적인 장점같다(!)

✅ || operator 사용하기

기존 코드에서는 arr.fill(0)을 활용해 0을 넣어두고 시작했었다.
새 코드에서는 || 를 사용해 더 간편하게 구현했다.

값이 유효할 경우 → 해당 값을
유효하지 않은 경우(Map에 존재하지 않음) → 0을 answer 배열에 푸시해줬다.

cnts와 mailCnt를 업데이트할 때도 || 를 사용했다.
해당 key-value가 Map에 존재하는 경우 → get으로 기존 값을 불러와 1 증가
존재하지 않는 경우 → 초기값 1

|| && operator는 짱짱맨임

특정 값이 있을 땐 해당 값으로, 없을 땐 기본값으로 설정해주고 싶을 때 || 가 매우 유용하다.

그 외 자잘한 문법 포인트

map에서 return 잘해주기

const reports = [...new Set(report)].map((item)=>{return item.split(' ')});
이 부분에서 return을 안해주니 reports 배열에 아무것도 들어있지 않았다.
(정확히는 report 배열 길이만큼 undefined가 들어있었다.)

map으로 배열 각 요소에 대해 원하는 작업을 해줬다면, return 을 해야 그 결과를 뱉어낼 수 있다.
위 코드의 경우 그렇게 뱉어낸 것들이 reports라는 새로운 배열에 담긴 것.


끝~!~!
얼른 JS로 푸는데 익숙해져서 Lv.2로 넘어가야징.
예전엔 새로운 개념 보면 '이런 게 있군' 하고 넘어갔는데 요즘은 '헐 이런 개쩌는 게 있다니'하는 감흥이 있다. 니꼴라스 쌤이 올려주시는 영상들도 매우 재밌게 보고 있는 요즘... 그래도 얇게나마 지식들이 쌓이고 있나보당 헤헤헤

profile
교육학과 출신 서타터업 프론트 개발자 👩🏻‍🏫

0개의 댓글