어느 어플이든 어느정도 진행이 나가고 나서부터는
database에서
한번을 깔끔한 데이터를 가져와 보기가 힘들다.
그 이유는
미래의 데이터의 확장성때문인데,
예를 들면, 가장 큰 예로 이미지가 있겠다.
페이스북 게시물을 보면 한 게시물에 여러개의 사진이 들어있다.
게시물의 내용과 이 사진의 데이터가 하나의 테이블에 존재하게 된다면
게시물 당 사진의 개수가 한정되어있어야하므로 유연성, 확장성이 극히 떨어지게 된다.
그래서 보통은 사진테이블과 게시물 테이블을 따로 두고
한 게시물에 대해서
게시물 테이블에서의 게시물 데이터와
사진 테이블에서 해당 게시물 사진 데이터들을 합쳐서(JOIN)
서버로 가져와야하는데
그렇게 되면 받아오는 배열의 결과는
우리가 원하는
한 게시물의 객체에 이미지배열이 프로퍼티로 들어가 있는것이 아니라
게시물 프로퍼티는 동일한게 중복되고 이미지 프로퍼티만 다른
괴상한 배열을 가져오게 된다.
- 우리가 원하는 배열 : A
[
{
board_idx : 1,
comment : "안녕하세요",
img_url : [
"http://aaaa.aaaaa.aaaaaa",
"http://bbbb.bbbbb.bbbbbb",
]
},
{
board_idx : 2,
comment : "안녕히계세요",
img_url : [
"http://cccc.ccccc.cccccc",
"http://dddd.ddddd.dddddd"
]
}
]
- database에서 가져오게 되는 배열 : B
[
{
board_idx : 1,
comment : "안녕하세요",
img_url : "http://aaaa.aaaaa.aaaaaa"
},
{
board_idx : 1,
comment : "안녕하세요",
img_url : "http://bbbb.bbbbb.bbbbbb"
},
{
board_idx : 2,
comment : "안녕히계세요",
img_url : "http://cccc.ccccc.cccccc"
},
{
board_idx : 2,
comment : "안녕히계세요",
img_url : "http://dddd.ddddd.dddddd"
}
]
이렇게 같은 게시물인데
이미지같이 프로퍼티의 배열로 나와야 함에도 불구하고
게시물객체가 중복되면서 배열로 나와야 하는 프로퍼티가 각자 갖고나오는
배열로밖에 가져올 수 없다.
이 바보같은 배열B를 우리가 원하는 배열A로 바꿀 수 있는 함수를 만드는 방법은 여러가지가 있다.
예를 들어
배열안에서 객체를 찾는 함수를 이용해, 즉
위의 B배열에서 board_idx으로 객체들을 구분할 수 있다고 하면
배열안의 각 board_idx을 갖는 객체를 찾아 img_url의 프로퍼티를 합쳐 하나의 객체로 만드는 방법이 있을 수 있다.
하지만 필자는 이 방법이 객체 하나하나를 찾는다는 것이 비효율적이라고 생각이 들어
더 좋은 생각을 연구해보았고
다음과 같은 함수를 만들어내었다.
위에서 설명한 상황에서 가져오는 배열은
위의 B처럼 같은 객체지만 배열로 묶여야 하는 프로퍼티를 제외하고 중복되는 배열을 가져왔을 때
따로 떨어져있지만 묶여서 나온다는 것을 이용했다.
위 사례를 통해 설명하자면, B를 보면
board_idx에 첫번째 게시물, 두번째 게시물, ... 이렇게 순서대로 나오는 것을 확인할 수 있다.
그렇다면 저 배열을 처음부터 쭉 읽으면서 img_url이 바뀌기 직전까지의 객체들을 묶으면 되는 것이다. 즉
즉, 저 바보배열에서 for문을 돌리고
img_url이 전의 img_url과 달라지면 직전까지의 객체들을 묶고
그 안의
img_url 프로퍼티를 배열화
해주면 되는 것이다.
대신 배열의 맨 처음과 맨 마지막 상황을 고려해주어야 한다.
함수를 직접 한번 보자
재배열 함수: (중복을 제거하는 함수 removeSameTag, removeSameImgUri는 맨 아래를 참고하면 되겠다.)
rearrangeBoard: (boardArr) => {
var boardAllResult = [];
var preImgArr = [];
var preBoardIdx = 0;
for (var idx in boardArr) {
//이전거랑 boardIdx가 다르면 이전 img_uri 배열 확정 저장 및 예비 이미지 배열(preImgArr)초기화
//첫번째와 마지막이 아닌경우
if (idx != 0 && idx != boardArr.length - 1) {
if (preBoardIdx != boardArr[idx].board_idx) { //이전 boardIdx와 다를때
// console.log(1);
boardArr[idx - 1].board_img_uri = preImgArr;
boardAllResult.push(boardArr[idx - 1]);
preImgArr = [];
preImgArr.push(boardArr[idx].board_img_uri);
} else {
// console.log(2);
//이전거랑 boardidx가 같으면 preImgArr(img_uri배열)에 자신의 img_uri 추가
preImgArr.push(boardArr[idx].board_img_uri);
}
}
if (idx == 0) {
// console.log(3);
preImgArr.push(boardArr[idx].board_img_uri);
}
//마지막
if (idx == boardArr.length - 1) {
if (preBoardIdx != boardArr[idx].board_idx) {
// console.log(4);
//boardIdx가 이전거랑 다를때
//전 board를 resultArr에 푸쉬
boardArr[idx - 1].board_img_uri = preImgArr;
boardAllResult.push(boardArr[idx - 1]);
//preImgArr초기화
preImgArr = []
preImgArr.push(boardArr[idx].board_img_uri);
boardArr[idx].board_img_uri = preImgArr;
//이 board 바로 result에 푸쉬
boardAllResult.push(boardArr[idx]);
} else {
// console.log();
//boardIdx가 이전거랑 같을때
preImgArr.push(boardArr[idx].board_img_uri);
boardArr[idx].board_img_uri = preImgArr;
boardAllResult.push(boardArr[idx]);
}
}
preBoardIdx = boardArr[idx].board_idx;
}
return boardAllResult;
}
위의 함수는
게시물 테이블,
이미지 테이블
이렇게 두 개의 테이블을 합친 것이고
만약 3개의 테이블을 합치고 똑같이 중복이 제거된 게시물배열로 만들려면 어떻게 해야할까
머리가 터지실 것 같아 이는 다음 포스팅에서 소개해보도록 하겠다.
- 위에서 중복을 제거하는데 사용된 함수 :
removeSameTag: (arr) => {
if(arr.length>0){
const result = [];
var s = 0;
var i = 0; //반복횟수
for (var e of arr) {
result.forEach(it => {
if (it == e) {
s = 1;
}
})
if (s != 1) {
result.push(e);
}
s = 0;
i++;
}
return result;
}
},
removeSameImgUri: (arr) => {
if(arr.length>0){
const result = [];
var s = 0;
var i = 0; //반복횟수
for (var e of arr) {
result.forEach(it => {
if (it == e) {
s = 1;
}
})
if (s != 1) {
result.push(e);
}
s = 0;
i++;
}
return result;
}
}
'인포테인먼트 - development > 알고리즘' 카테고리의 다른 글
[알고리즘] DATABASE에서 여러 테이블을 JOIN해서 가져온 데이터배열 중복 제거, 정리(2) (0) | 2020.04.02 |
---|
댓글