이번 스터디의 키워드는 객체이다!
객체를 활용하면 쉽고 깨끗한 코드를 짤 수 있다는 걸 느꼈다. 뿐만 아니라 시간복잡도도 줄일 수 있다구!!🧚♂️
오픈채팅방 문제는 사용자가 채팅방에 들어오고(Enter) 나가는 것(Leave)과 닉네임을 바꾼(Change) 기록이 담겨져 있는 문자열이 배열로 들어온다.
내가 푼 방식은
1️⃣ 먼저 주어진 배열을 돌며 아이디 - 닉네임을 짝 지은다.
key : value
형태로 짝이 지어져 있으니 갖다 쓰기 편하다.2️⃣ 그리고 다시 주어진 배열을 돌면서 사용자가 들어오거나 나가는 행위일 경우, 배열에 푸쉬해 반환한다.
if else
조건문을 쓰느냐, 객체를 쓰느냐 고민이 되었다. 코드는 아래와 같다.
function solution(record) { const user = record.reduce((obj, cur) => { if (cur[0] === 'L') return obj; const curArr = cur.split(' '); obj[curArr[1]] = curArr[2]; return obj }, {}); const answer = record.reduce((acc, cur) => { if (cur[0] === 'C') return acc; const curArr = cur.split(' '); if (cur[0] === 'E') // if else로 분기하여 배열에 집어넣음 acc.push(user[curArr[1]] + '님이 들어왔습니다.'); else if (cur[0] === 'L') acc.push(user[curArr[1]] + '님이 나갔습니다.'); return acc; }, []); return answer; }
function solution(record) { const user = record.reduce((obj, cur) => { if (cur[0] === 'L') return obj; const curArr = cur.split(' '); obj[curArr[1]] = curArr[2]; return obj }, {}); const msg = { Enter : '님이 들어왔습니다.', Leave : '님이 나갔습니다.' } // 객체를 선언해 const answer = record.reduce((acc, cur) => { if (cur[0] === 'C') return acc; const curArr = cur.split(' '); acc.push(user[curArr[1]] + msg[curArr[0]]); // 바로 넣어줌 return acc; }, []); return answer; }
뿐만 아니라 사실 완전 처음에는 사용자의 아이디 - 닉네임 짝을 지을 때에도, if
로 이미 있는 경우를 빼고 객체에 넣어주도록 했다. 하지만 비교해보니, 그냥 할당하는 것이 더 빠르다는 걸 알게 되었다. 나중에 할당된 것이 쓰이므로!
‼️ 여기서 잠깐! 호준멘토님께서 우리 프로젝트 코드를 보며 if else
를 지양하라고 말씀해주셨던 게 생각이 났다.
이렇게 작은 코드에서도 시간 차이가 나는 걸 눈으로 확인해보니,
"😫 우리 프로젝트에서 코드가 실행될 때는 얼마나 많은 시간이 잡아먹혔을까!" 라는 생각이 들었다.
그래서 요즘 다시 42gg 업데이트로 코드를 보고 있는데, 리팩토링할 코드가 수두룩해보였다. 이만큼이나 성장한 거겠지?
알림 메시지를 반환하는 함수도 이렇게 깔끔하게 바꿀 수 있다.
function makeContent(data: Noti) { if (data.type !== 'announce' && data.time) { const gameTime = gameTimeToString(data.time); if (data.type === 'matched') return `${gameTime}에 신청한 매칭이 성사되었습니다.`; else if (data.type === 'canceledbyman') return `${gameTime}에 신청한 매칭이 상대에 의해 취소되었습니다.`; else if (data.type === 'canceledbytime') return `${gameTime}에 신청한 매칭이 상대 없음으로 취소되었습니다.`; } else { return `${data.message}`; }
function makeContent(data: Noti) { const messages = { matched: '에 신청한 매칭이 성사되었습니다.', canceledbyman: '에 신청한 매칭이 상대에 의해 취소되었습니다.', canceledbytime: '에 신청한 매칭이 상대 없음으로 취소되었습니다.' } if (data.type !== 'announce' && data.time) { const gameTime = gameTimeToString(data.time); return gameTime + messages[data.type] ; } else { return data.message ; }
짠! 이렇게 되면, data.type
에 새로운 타입이 생겨도, message
객체에 추가만 해주면 바로 쓸 수 있다. 만약 if else
문으로 작성했다면, 타입이 생겨날 때마다 else if ~
이렇게 계속 작성해주는 무한 일거리들이 생겨나겠지!
이렇게 리팩토링할 거리들이 계속 보여서 신기하다. 조건문이 많아지면 렌더링 시간도 늘어날테고, 그럼 사용성도 떨어질테고... 으아아아~ 😵💫
조만간 재귀함수도 정리해서 올려야지 했는데, 프로젝트를 다시 시작하게 되면서 쉽지 않다. 그렇지만 정리하는 걸 게을리 했다간 기억에 남지 않을 것 같아 두렵다. 스터디원들을 보면서 새로 알게된 것, 느낀 것을 바로바로 정리해야지! (다짐다짐)
위의 코드처럼 바꾸려고 하니... 에러가 났다! 구글링해보니, 객체의 키 값으로 접근하는데 그 타입이 정해져 있지 않기 때문이라고 한다. 그래서 이렇게 객체에도 타입을 넣어주면 가능하다.
function makeContent(data: Noti) { const messages: { [key: string]: string } = { // 객체의 타입을 정해주자!! matched: '에 신청한 매칭이 성사되었습니다.', canceledbyman: '에 신청한 매칭이 상대에 의해 취소되었습니다.', canceledbytime: '에 신청한 매칭이 상대 없음으로 취소되었습니다.', }; if (data.type !== 'announce' && data.time) { const gameTime = gameTimeToString(data.time); return gameTime + messages[data.type]; } else { return data.message; } }
타입스크립트는 정말 접근하는 모든 값의 타입을 지정해줘야 하구나...? 꼼꼼한 언어야 증말...
우와...!! 시간이 지날수록 더더 멋진 코드가 만들어지는 거 같아요!! 멋있다 정말!!! 굿굿~!!😊