문제 : 2022 KAKAO BLIND RECRUITMENT > 신고 결과 받기
https://school.programmers.co.kr/learn/courses/30/lessons/92334
reportArray
을 만든다.reportedUsers
을 만든다.id_list
를 key값, 그리고 2번에서 뽑은 배열 reportedUsers
를 value값으로 받는 객체ObjectId
를 만든다.susUser
를 구한다.objectId
와 4번에서 뽑은 정지당한 유저 리스트susUser
배열을 이중반복문을 돌려서 objectId
의 value값이 정지당한 유저 배열의 포함(includes)됐을 때 카운팅을 올리고 그 카운트를 정답 배열에 푸쉬하고 리턴한다. 결국 통과하지 못하고 80~90점 초반까지 점수를 받은 풀이이다. 인자로 받는 배열 report
의 경우 범위가 1 ≤ report
의 길이 ≤ 200,000 이고, report
를 활용한 신고당한 유저 reportedUsers
를 이차원 배열로 사용하여 반복문, 이중 반복문을 자주 사용하게 된다. 마지막 정답을 리턴 할때는 .includes()
를 쓰기 때문에 또 루프가 더 돌게 되고.. 그래서 3,10,11 테스트의 경우 시간초과로 통과하지 못한다.
function solution(id_list, report, k) {
//1. 중복 신고 제거한 이차원 배열 만들기
const reportArray = [...new Set(report)].map(x => x.split(" "))
//2. 신고 당한 유저를 배열 원소로 받으면서 전체 유저의 인덱스와 같은 이차원 배열을 만듬
let reportedUsers = [];
for(i in id_list) {
let indivisualReportArray = [];
for(j in reportArray) {
if(reportArray[j][0] === id_list[i]){
indivisualReportArray.push(reportArray[j][1])
}
}
reportedUsers.push(indivisualReportArray)
}
//3. 전체 유저 `id_list`를 key값, 그리고 2번에서 뽑은 배열 `reportedUsers`의 원소들을 value값으로 받는 객체`ObjectId`를 만든다.
const objectId = {}
id_list.forEach((key, i) => objectId[key] = reportedUsers[i])
//4. 신고당한 유저 중 정지당한 유저를 구한다.
const getSusUser = (reportedUsers, k) => {
//신고당한 유저 이차원배열 => 1차원배열
let newReportedUsers = reportedUsers.flat()
// 신고당한 유저(key)와 신고당한 횟수(value)로 이루어진 객체를 만든다. (중복횟수 체크)
const reportedUserCount = {};
newReportedUsers.forEach(x => {
reportedUserCount[x] = (reportedUserCount[x] || 0) +1
})
//위 객체에서 신고당한 횟수(value)가 k이상인 key를 뽑아 배열로 리턴한다.
let susUser = [];
for(const key in reportedUserCount) {
if(reportedUserCount[key] >= k)
susUser.push(key)
}
return susUser
}
//정지당한 유저 리스트 배열
const susUser = getSusUser(reportedUsers, k)
//5. 메일받은 횟수(정답) 뽑기
//3번에서 뽑은 객체`objectId`와 4번에서 뽑은 정지당한 유저 리스트`susUser` 배열을 이중반복문을 돌려서 `objectId`의 value값이 정지당한 유저 배열의 포함(includes)됐을 때 카운팅을 올리고 그 카운트를 정답 배열에 푸쉬하고 리턴한다.
let answerArray = []
for(const key in objectId) {
let count = 0;
for(i in susUser) {
if(objectId[key].includes(susUser[i])) {
count++
}
}
answerArray.push(count)
}
return answerArray
}
newReport
을 만든다.reportedUsers
로 받는다.suspenededUserObject
를 만든다.if
문에 있는 객체의 key값으로 다른 배열의 원소를 넣는 방법을 이번에 배우게 됐다. 그리고 1번에서 뽑은 newReport
와 2번에서 뽑은 reportedUsers
의 길이가 같기 때문에 같은 반복문안에서 처리하며 정지당한 유저를 신고한 유저를 나열한 배열을 구할수 있게 된다.mailCountObject
를 만든다.id_list
의 원소가 5번에서 뽑은 객체 mailCountObject
의 key일 경우 mailCountObject
의 value를 정답 배열에 넣는다. 존재하지 않을 경우(else) 0을 푸시한다.본인 풀이와 차이점은 reportedUsers
를 일차원 배열로 만들기 때문에 이중반복문을 한번 줄일 수 있는 것과 배열의 반복문 중 배열의 원소를 비교하는 객체의 key값으로 활용하여 .includes()
나 이중반복문을 줄인다는 점이다.
function solution(id_list, report, k) {
//1. 중복 신고를 제거한 이차원 배열 만들기
const newReport = [...new Set(report)].map(x => x.split(" "))
//2. 신고당한 유저의 목록을 일차원 배열 `reportedUsers`로 받는다.
let reportedUsers = [];
for(i in newReport) {
reportedUsers.push(newReport[i][1])
}
//3. 신고 당한 유저를 카운팅하고 정지당한 유저의 목록을 key값, 그리고 그 유저가 신고당한 횟수를 value값으로 받은 객체 `suspenededUserObject`를 만든다.
const getSusUser = (reportedUsers, k) => {
// 신고당한 유저와 그 카운트를 객체로 만든다.
const reportedUserCount = {};
reportedUsers.forEach(x => {
reportedUserCount[x] = (reportedUserCount[x] || 0) +1
})
//바로 위에서 만든 객체 중 value가 k보다 작을 경우 삭제한다 => 정지당한 유저만 남는다.
for(const key in reportedUserCount) {
if(reportedUserCount[key] < k)
delete reportedUserCount[key]
}
return reportedUserCount
}
//정지당한 유저의 목록을 key값, 그 유저가 신고당한 횟수를 value값으로 받는 객체
const suspendedUserObject = getSusUser(reportedUsers, k)
//4. 정지당한 유저를 신고한 유저의 목록을 나열한 배열로 만든다.
// (신고당한 유저 목록 배열`reportedUsers`의 원소)가 (정지당한 유저 목록 객체 `suspendedUserObject`의 key와 동일할 경우) (1번에서 뽑은 이차원 배열 `newReport` 중 신고자를 뜻하는 원소 newReport[i][0]을) (빈 배열에 push하여 정지당한 유저를 신고한 유저의 목록을 나열한 배열`reporterArray`를 만든다).
// 문장 호흡이 길어져서 헷갈리지 않게 괄호로 감싸겠다.
let reporterArray = [];
for (i in reportedUsers) {
if(reportedUsers[i] in suspendedUserObject) {
reporterArray.push(newReport[i][0])
}
}
//5. 정지 메일을 받은 유저를 key, 그 메일 수신 횟수를 value로 한 객체를 만든다.
//위 4번에서 뽑을 배열 `reporterArray`은 정지당한 유저를 신고한 유저의 나열이기 때문에 중복 개수를 체크하여 메일 받은 유저와 메일 수신 횟수를 구한다.
const mailCountObject = {}
reporterArray.forEach(x => {
mailCountObject[x] = (mailCountObject[x] || 0) +1
})
//6. 전체 유저 목록인 배열 `id_list`의 원소가 5번에서 뽑은 객체 `mailCountObject`의 key일 경우 `mailCountObject`의 value를 정답 배열에 넣는다. 존재하지 않을 경우(else) 0을 푸시한다.
let answerArray = []
for(i in id_list) {
if(id_list[i] in mailCountObject) {
answerArray.push(mailCountObject[id_list[i]])
}
else(answerArray.push(0))
}
return answerArray
}