https://programmers.co.kr/learn/courses/30/lessons/92334?language=javascript
sol1
let id_list = ["muzi", "frodo", "apeach", "neo"];
let report = ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
let k = 2
let userlist = id_list.reduce((result,currentID)=> {
result[currentID] = [0,[]];
return result
},{});
for(let x of new Set(report)) {
let [REPORT_ID,ID] = x.split(' ');
userlist[REPORT_ID][1].push(ID);
userlist[ID][0]++;
}
let ban = id_list.filter(el => userlist[el][0]>=k);
let answer = id_list.map(id => {
return userlist[id][1].filter(el => {
return ban.includes(el);
}).length;
})
console.log(answer) // [ 2, 1, 1, 0 ]
객체의 key, value를 이용해 맞는 조건을 탐색하고, map메서드를 이용해 결과적으로 메일을 받게 될 횟수만 나오도록 한다.
1.
let userlist = id_list.reduce((result,currentID)=> {
result[currentID] = [0,[]];
return result
},{});
console.log(userlist)
// {
// muzi: [ 0, [] ],
// frodo: [ 0, [] ],
// apeach: [ 0, [] ],
// neo: [ 0, [] ]
// }
처음엔 filter메서드를 이용해 객체에 하나하나 담으려고 했지만, reduce메서드를 이용해 한번에 객체로 만드는 게 보기 좋았다.
각 유저가 신고당한 횟수를 카운팅하기 위한 0과 유저가 누구를 신고했는지 담을 빈 배열을 만든다
2.
for(let x of new Set(report)) {
let [REPORT_ID,ID] = x.split(' ');
userlist[REPORT_ID][1].push(ID);
userlist[ID][0]++;
}
console.log(userlist)
// {
// muzi: [ 1, [ 'frodo', 'neo' ] ],
// frodo: [ 2, [ 'neo' ] ],
// apeach: [ 0, [ 'frodo', 'muzi' ] ],
// neo: [ 2, [] ]
// }
문제 조건중 신고는 여러번 할 수 있지만, 한 사람에 대한 신고는 한 번만 처리한다고 했으므로 Set에 담아 중복을 제거해준다. Set에 담은 배열은 for.. of 문으로 순회하며 요소들을 꺼내 쓰는 게 제일 익숙하다. 신고자와 신고당한 유저가 공백으로 구분되어 있으므로 split(' ')을 사용해 구분시켜 배열에 담아둔다.
신고자를 앞서 만들었던 userlist 객체의 프로퍼티 키로 찾고 누구를 신고했는지 push 해준다. 신고 당한 유저와 userlist 프로퍼티 키가 같을 때마다 카운트를 올려 신고당한 횟수를 체크한다.
3.
let ban = id_list.filter(el => userlist[el][0]>=k);
let answer = id_list.map(id => {
return userlist[id][1].filter(el => {
return ban.includes(el);
}).length;
})
console.log(ban) // [ 'frodo', 'neo' ]
console.log(answer) // [ 2, 1, 1, 0 ]
ban에는 신고당한 횟수가 이용정지 대상인 k 이상 누적된 유저를 필터링해 담는다.
answer 에는 유저들이 각각 신고한 유저명단인 userlist 프로퍼티 값[1]에 이용정지된 대상만 남도록 하고 length로 배열의 길이를 반환한다.
sol2
let id_list = ["muzi", "frodo", "apeach", "neo"];
let report = ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
let k = 2
function solution(id_list, report, k) {
let answer = new Array(id_list.length);
answer.fill(0);
let setReport = [...new Set(report)];
let arr = [];
let user = [];
let reportingUser = [];
let reportedUser = [];
for (let i = 0; i < setReport.length; i++) {
arr.push(setReport[i].split(' '));
}
for (let i = 0; i < id_list.length; i++) {
user.push({ name: id_list[i], reported: 0 });
}
for (let i = 0; i < user.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (user[i].name == arr[j][1]) {
user[i].reported++;
}
}
}
for (let i = 0; i < user.length; i++) {
if (user[i].reported >= k) {
reportingUser.push(user[i].name);
}
}
for (let i = 0; i < reportingUser.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (reportingUser[i] == arr[j][1]) {
reportedUser.push(arr[j][0]);
}
}
}
for (let i = 0; i < reportedUser.length; i++) {
for (let j = 0; j < user.length; j++) {
if (reportedUser[i] == user[j].name) {
answer[j]++;
}
}
}
return answer;
}
console.log(solution(id_list,report,k)) // [ 2, 1, 1, 0 ]
처음부터 Set 을 이용해 중복을 걸러 객체에 아이디와 신고당한 횟수를 담고 각 조건별 배열을 따로 만들어 담고 비교한다. filter와 reduce 메서드를 제대로 사용하지 못해서 방법을 찾을 때 이런 방법으로 풀었다면 문제 해결하기에 훨씬 빨랐을 것 같다. 문제를 조건별로 구분 후 해결하는 연습을 많이 해야겠다.
'Study > Algorithm' 카테고리의 다른 글
[BEAKJOON / node.js] 1439 뒤집기 (0) | 2022.06.08 |
---|---|
[BEAKJOON / node.js] 2775 부녀회장이 될테야 (0) | 2022.06.07 |
<BEAKJOON / node.js> 1181 단어정렬 (0) | 2022.05.29 |
[BEAKJOON / node.js] 13305 주유소 (0) | 2022.05.28 |
<BEAKJOON / node.js> 11399 ATM (0) | 2022.05.24 |