본문 바로가기
  • 포르쉐타고싶다
인포테인먼트 - development/알고리즘

[알고리즘] DATABASE에서 여러 테이블을 JOIN해서 가져온 데이터배열 중복 제거, 정리(1)

by 지오ㄴl 2020. 3. 21.

어느 어플이든 어느정도 진행이 나가고 나서부터는

 

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;
        }
        
    }

 

반응형

댓글