이전에 구현하였던 폴더 생성 함수에서 문제가 발생하여 해결하다가 페이지 이름을 정하는 로직을 다시 보게 되었는데 이렇게 결정했던 이유도 정리해야겠다는 생각이 들었다.
( 하나의 히스토리를 적어보자면...
생성 시에 사용자가 이름을 적은 후 생성 요청하는 함수였더랬다)
생성되는 새로운 페이지의 형식은 "페이지 {Number}"이고
가장 기본적으로 생각했던 것은 새롭게 생성되는 폴더 이름에 대해 중복성을 제거하고 싶었다
전체 항목 수 +1 ?
- 우선, 처음 회원가입을 하였을 때 제공되는 기본 페이지에는 일반 체험판 타이틀이 제공된다.
그러므로 이러한 경우에서 새 페이지를 생성한다면 처음부터 페이지 2가 생성되겠지..?
- 페이지 15를 생성한 후 중간의 페이지를 삭제하고 다시 페이지 생성을 누르면 페이지 15가 또 생성될 것이다..
최댓값 +1 ?
- 사용자가 페이지를 수정할 때 임의로 "페이지 20000"으로 해놓는다면 다음 생성되는 페이지 이름은 "페이지 20001"이 될 것이다...
즉, '페이지'가 포함된 제목의 번호 중 가장 큰 연속된 번호로 설정된다. (페이지 1, 페이지 4, 페이지 5의 경우 페이지 2가 생성)
이전 코드에서 문제가 되었던 것은 break를 걸어주고 있던 부분이었다.
만약, 사용자가 "페이지 {임의의 문자열}" 등으로 타이틀을 수정한 경우 parInt하는 부분에서 NaN이 제공되고 이로인해 sort가 적용안되고.. 이로인해 break가 NaN나온 부분에서 바로 걸려 버린다.
for (let i = 0; i < pageNumbers.length; i++) {
if (pageNumbers[i] !== availablePageNumber) {
break;
}
availablePageNumber++;
}
우리는 타이틀의 중복을 허용하고 있다.
NaN을 필터링하고 전체 for 루프를 도는 코드로 수정하였다.
const createFolder = () => {
let PAGE_NUMBER = 1;
const pageNumbers = folderData.PageList.filter(({ title }) =>
title.includes('페이지')
)
.map(({ title }) => parseInt(title.replace('페이지', ''), 10))
.filter(num => !isNaN(num))
.sort((a, b) => a - b);
for (let i = 0; i < pageNumbers.length; i++) {
pageNumbers[i] === PAGE_NUMBER && PAGE_NUMBER++;
}
}
이후, '페이지'가 포함된 제목의 번호 중에 비어 있는 첫 번째 번호를 찾는 방법을 생각했다.
for 루프가 전체 배열을 순회해야 하는 것에 비해 find 메서드를 이용하면 조건을 만족하는 첫 번째 요소를 찾으면 루프가 바로 종료된다. 순차적으로 페이지가 채워진 경우에는, 이 코드가 조금이나마 더 빠르게 작동할 수 있을 것이다.
그러나.. 이 또한 사용자가 수정하는 한에서는 중복을 허용하고 있어서 해당 find 메서드를 이용하려면 필터링하는 로직이 더 추가되어야 한다.
좋은 글 감사합니다. 자주 올게요 :)