게임을 저장하고 불러오는 작업을 진행하고 있습니다.
db 작업도 하고있는 중인데, 여태 해본적이 없어서 꽤나 찾아보고 해야하네요..
sequelize를 통해 작업을 하고 있는데,
데이터 갯수를 몇개 정해서 가져오고 이것을 랜덤으로 섞어서 프론트로 내려줘야하는 경우가 생겼습니다.
원래 작업했던 순서는..
프론트에서 모든 배열을 받은 후 배열의 갯수를 특정하고 그 다음 랜덤하게 섞는 작업을 했었습니다만...
모든 데이터를 받는 것부터가 너무 낭비였습니다.
그래서 이 부분을 수정하면서 랜덤하게 섞는것도 가능하단것을 알게되었습니다.
limit을 통해 몇개 가져올지,
order를 통해 어떤형식으로 가져올지 정할 수 있습니다.
다만 어떤것이 성능상 좋은지는 잘 모르겠군요... (order부분)
router.get('/nonsensequiz', async (req, res, next) => { // POST /game/nonsensequiz
try {
const quiz = await NonsenseQuiz.findAll({
limit: 20,
order: sequelize.random()
});
res.status(200).json(quiz);
} catch (error) {
console.error(error);
next(error);
}
});
프론트에서 작업했던 코드도 한 번 보겠습니다.
원래는 sort로 간단하게 끝내려다가 피셔-에이츠 셔플 알고리즘으로 작업하기로 결정했습니다.
sort는 랜덤정렬이라고 하기에는 빈도 수에 차이가 꽤 발생한다고 합니다.
아래 블로그글을 참고해보세요 (블로그 글에서 해답보기 클릭하셔야 글 확인이 가능합니다.)
ko.javascript.info/task/shuffle
피셔-에이츠 셔플 알고리즘은..
배열의 첫번째부터 시작해 배열의 크기만큼 반복하면서 임의의 요소와 해당 요소를 바꿔치기하는 알고리즘입니다.
일단 셔플하기 전에 원본 데이터를 deep copy해주었습니다.
function shuffleArray (arr){
let temp = arr.map((v) => {
return cloneObject(v);
});
for(let i = temp.length - 1; i > 0; i--){
let j = Math.floor(Math.random() * (i + 1));
[temp[i], temp[j]] = [temp[j], temp[i]];
}
return temp;
};
function cloneObject(obj) {
let clone = {};
for (var key in obj) {
if (typeof obj[key] == 'object' && obj[key] != null) {
clone[key] = cloneObject(obj[key]);
} else {
clone[key] = obj[key];
}
}
return clone;
}
현재 db에서 배열을 섞어서 내려주는 작업을 진행해서 프론트쪽 코드들은 사용안하게됐지만,
성능상 비교를 하여 어느쪽이 좋은지 판단해서 작업하는 작업자가 되어야겠습니다.