[JS] 배열 중복 제거 및 Map 객체

조병근·2023년 3월 26일
0

알고리즘을 풀다보니 Map 객체라는 것을 새로 알게 되었다.
그래서 정리해보며 다른 사람들과 내가 쉽게 이해한대로 공유하면 좋겠다 생각이 들었다.
먼저 풀었던 문제는 다음과 같다

프로그래머스 level1 신고 결과 받기

사실 이 문제는 처음에 30분동안 풀지 못해 풀이를 이해하고, 다시 풀게 되었다.
근데 다시 풀면서도 Map을 까먹어 버린 것이다. 그래서 다음과 같이 풀이를 했다.

  1. 배열 중복 제거를 통해 중복 신고 제거
  2. id_list에 있는 각 id에 대한 객체 생성
  3. 신고를 받은 id : 신고 받은 횟수 로 객체 생성
  4. 신고 받은 횟수가 k번 이상인 object만 찾아 report의 배열과 비교하여 다시 신고자 : 신고한 id가 정지먹은 횟수 로 객체 생성
  5. answer에 대입
function solution(id_list, report, k) {
    var answer = [];
    report=[...new Set(report)];
    let reporterObj=new Object();
    id_list.map((v)=>{ // id별로 신고 성공횟수 0으로 초기화
        reporterObj[v]?1:reporterObj[v]=0;
    }) 
    
    let reportedObj=new Object();
    report.map((v)=>{ // 신고 받은 id 횟수
        let [reporter,reportee]=v.split(" ");
        reportedObj[reportee]?reportedObj[reportee]++:reportedObj[reportee]=1;
    }) 
    
    Object.keys(reportedObj).map((v)=>{
        if(reportedObj[v]>=k){
            report.forEach((element)=>{
                let [reporter,reportee]=element.split(" ");
                if(reportee===v){
                    reporterObj[reporter]?reporterObj[reporter]++:reporterObj[reporter]=1;
                }
            })
        }
    }) // 만약 특정 id가 두번 이상 신고 당했다면, 그 신고당한 id를 신고한 신고자 +1
    id_list.map((v)=>{
        if(reporterObj[v]===null){
            answer.push(0);
        }else{
            answer.push(reporterObj[v]);
        }
    })
    return answer;
}

이런 엉터리 알고리즘을 먼저 보여주게되어 죄송하단 말씀을 먼저 하겠습니다.
프로그래머스에 돌리면 map을 4번이나 돌리니 당연히 시간 초과가 난다.
풀면서도 아 이게 맞는 방법이긴한데... 효율성이 엉망이네 하면서 풀었다.

그래서 배열 중복 제거 방법과 Map 객체에 대해 정리해보고자 한다.

배열 중복 제거

정말정말 쉽다. Set 객체를 이용하는 방식이다.
Set은 중복된 값은 가질 수 없다는 게 특징이다.
그렇기에 배열을 Set으로 변환한 뒤 다시 배열로 바꿔주는 방법이다.
위의 풀이에서 보면

report=[...new Set(report)];

이 부분이 배열 중복제거에 해당한다.
report를 Set으로 바꿔준 뒤, 다시 []로 감싸주어 배열로 바꿔주는 것이다.
실제 결과를 보면 차이를 느낄 수 있다.

배열 바꿔주기 전
["ryan con", "ryan con", "ryan con", "ryan con"]

바꿔준 후
["ryan con"]

Map 객체

map()함수는 많이 사용하지만 Map 객체에 대해서는 잘 모르고 있었다.

let max = new Map();
​
// set으로 맵 객체에 삽입
max.set('id', 0);
max.set('이름', '마이클');
max.set('전공', '영문학');
max.set('나이', 25);
​
// 이차원 배열로 넘겨주는 것도 가능합니다
let michael = new Map([
  ['id', 0],
  ['이름', '마이클'],
  ['전공', '영문학'],
  ['나이', 29],
]);
​
// get으로 맵 객체 조회
max.get('이름'); // "마이클"
​
// delete로 삭제
max.delete('나이'); // 삭제가 성공하면 true를 반환
​
// clear로 맵 안의 프로퍼티 전부삭제
max.clear();

다음과 같이 key: value 형태로 이루어져있다. key로 조회, 삭제가 가능하고 문자열 아닌 값도 key로 사용할 수 있다는 장점이 있다. Map 객체는 중복을 허용하지 않는다.

위의 문제를 Map 객체를 이용해서 다시 풀어봤다.

function solution(id_list, report, k) {
    var answer = [];
    let reports=[...new Set(report)].map((v)=>{return v.split(" ")});
    let count=new Map();
    reports.map((v)=>{ // v[1]은 신고받은 사람
        count.set(v[1],count.get(v[1])+1||1);
    });
    let good=new Map();
    reports.map((v)=>{ // id별 신고 성공 횟수 
        if(count.get(v[1])>=k){
            good.set(v[0],good.get(v[0])+1||1);
        }
    })
    answer=id_list.map((v)=>good.get(v)||0);
    return answer;
}

이렇게 하니 시간 초과도 발생하지 않고 풀렸다.

결론
Map 객체를 활용하면 Object를 여러개 생성하는 것보다 편리하다!

profile
노력하면 못할 일이 없다

0개의 댓글