투케이2K

510. (javaScript) [간단 소스] 자바스크립트 커스텀 json key 정렬 함수 생성 및 string , number , date 타입 asc , desc 정렬 수행 본문

JavaScript

510. (javaScript) [간단 소스] 자바스크립트 커스텀 json key 정렬 함수 생성 및 string , number , date 타입 asc , desc 정렬 수행

투케이2K 2026. 3. 13. 20:01
728x90
반응형

[개발 환경 설정]

개발 툴 : Edit++

개발 언어 : JavaScript

 

[소스 코드]

-----------------------------------------------------------------------------------------
[사전 설명 및 설정 사항]
-----------------------------------------------------------------------------------------

- 개발 환경 : Web


- 개발 기술 : JavaScript (자바스크립트) / JSON / Object.keys


- 사전) 👉 자바스크립트 객체 복사 >> 얕은 복사 vs 깊은 복사 간력 설명 : 

  >> 얕은 복사 : 

    - 속도 : 빠름
    - 중첩 데이터 안전성 : ❌ 불안함 (참조 공유됨)
    - 사용 상황 : 단순 값 복사, 읽기 전용
    - 대표 메서드 : slice, ..., Object.assign

  >> 깊은 복사 : 

    - 속도 : 상대적으로 느림
    - 중첩 데이터 안전성 : ✅ 안전 (참조 완전 분리)
    - 사용 상황 : 원본 보호, 상태 관리, 중첩 구조
    - 대표 메서드 : structuredClone, cloneDeep, JSON.parse

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[소스 코드]
-----------------------------------------------------------------------------------------

<!DOCTYPE HTML>
<html lang="ko">
<head>
    <title>javaScriptTest</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">


    <!-- 반응형 구조 만들기 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">


    <!-- 내부 CSS 스타일 지정 -->
    <style>

        html, body {
            width: 100%;
            height: 100%;
            margin : 0 auto;
            padding : 0;
            border : none;
            background-color: #666;
        }

    </style>





    <!-- [CDN 주소 설정] -->
    <script src="https://code.jquery.com/jquery-latest.min.js"></script>






    <!-- [자바스크립트 코드 지정] -->
    <script type="module">
        
        window.onload = async function() {
          console.log("[window onload] : [html 최초 로드 및 이벤트 상시 대기 실시] : [start]");

          try {


            // --------------------------------------------
            // ✅ [string , number , date 타임 JSON 정렬 커스텀 함수 생성]
            // --------------------------------------------
            function compareByJsonKey(key, { order = 'asc', type = 'string', locale = 'ko-KR' } = {}) {

              // ----------------------------------------------
              // 정렬 방향 계수 (dir)
              // ----------------------------------------------
              // 각 타입 로직을 한 번만 구현하고, 마지막에 * dir로 방향을 제어
              // ----------------------------------------------
              // a - b가 오름차순이라면, 내림차순에서는 -(a - b)가 되어야 하므로 -1을 곱함
              // ----------------------------------------------
              // asc = 오름 차순 (작은 순서) / desc = 내림 차순 (큰 순서)
              // ----------------------------------------------
              const dir = order === 'desc' ? -1 : 1; 

              return (a, b) => { // (비교 함수) 클로저 반환

                try {

                  // 비교 대상 값 추출 (옵셔널 체이닝) : 객체 a, b에서 key에 해당하는 값을 안전하게 추출
                  const va = a?.[key];
                  const vb = b?.[key];

                  // 누락값 (null/undefined) 처리 : 항상 끝으로
                  const aMissing = va == null;
                  const bMissing = vb == null;

                  if (aMissing && bMissing) return 0; // 둘 다 누락 → 동등(0)
                  if (aMissing) return 1; // a만 누락 → a가 더 큼(1) ⇒ 오름차순에서 뒤로 감
                  if (bMissing) return -1; // b만 누락 → b가 더 큼(-1) ⇒ a가 앞으로 감

                  if (type === 'number') {
                    const na = Number(va);
                    const nb = Number(vb);
                    if (Number.isNaN(na) && Number.isNaN(nb)) return 0;
                    if (Number.isNaN(na)) return 1;
                    if (Number.isNaN(nb)) return -1;

                    console.warn('type : number : ', (na - nb) * dir);
                    return (na - nb) * dir;                    
                  }

                  if (type === 'date') {
                    const ta = va instanceof Date ? va.getTime() : new Date(va).getTime();
                    const tb = vb instanceof Date ? vb.getTime() : new Date(vb).getTime();
                    if (!Number.isFinite(ta) && !Number.isFinite(tb)) return 0;
                    if (!Number.isFinite(ta)) return 1;
                    if (!Number.isFinite(tb)) return -1;

                    console.warn('type : date : ', (ta - tb) * dir);
                    return (ta - tb) * dir;
                  }

                  // string (default) — 대소문자/악센트 무시해서 정렬
                  console.warn('type : string : ', String(va).localeCompare(String(vb), locale, { sensitivity: 'base' }) * dir);
                  return String(va).localeCompare(String(vb), locale, { sensitivity: 'base' }) * dir;

                }
                catch(exception){
                  console.error('compareByJsonKey : exception : ', exception);

                  return 0; // 둘 다 누락 → 동등(0) : 원본 형태 그대로 표시 설정
                }
              
              };
            };


            // --------------------------------------------

            // [정렬을 수행할 array json 데이터 생성]
            // --------------------------------------------
            const origin = [
              {
                name: 'a',
                age: 19,
                date: new Date('2026-03-13T15:12:30')
              },
              {
                name: 'c',
                age: 10,
                date: new Date('2026-03-12T10:32:20')
              },
              {
                name: 'b',
                age: 30,
                date: new Date('2026-03-09T12:10:40')
              },
              {
                name: 'A',
                age: 12,
                date: new Date('2026-03-10T09:50:10')
              }
            ];

            
            // --------------------------------------------
            // ✅ [특정 문자열 기준 : 데이터 정렬 수행]
            // --------------------------------------------
            const stringSorted = JSON.parse(JSON.stringify(origin));

            // [{"name":"a","age":19,"date":"2026-03-13T06:12:30.000Z"},{"name":"A","age":12,"date":"2026-03-10T00:50:10.000Z"},{"name":"b","age":30,"date":"2026-03-09T03:10:40.000Z"},{"name":"c","age":10,"date":"2026-03-12T01:32:20.000Z"}]
            stringSorted.sort(compareByJsonKey('name', { order: 'asc', type: 'string' })); // 작은 순서
            
            console.log('stringSorted : asc : ', JSON.stringify(stringSorted));

            //  [{"name":"c","age":10,"date":"2026-03-12T01:32:20.000Z"},{"name":"b","age":30,"date":"2026-03-09T03:10:40.000Z"},{"name":"a","age":19,"date":"2026-03-13T06:12:30.000Z"},{"name":"A","age":12,"date":"2026-03-10T00:50:10.000Z"}]
            stringSorted.sort(compareByJsonKey('name', { order: 'desc', type: 'string' })); // 큰 순서
            
            console.log('stringSorted : desc : ', JSON.stringify(stringSorted));

            
            // --------------------------------------------
            // ✅ [특정 문자열 기준 : 데이터 정렬 수행]
            // --------------------------------------------
            const numberSorted = JSON.parse(JSON.stringify(origin));

            // [{"name":"c","age":10,"date":"2026-03-12T01:32:20.000Z"},{"name":"A","age":12,"date":"2026-03-10T00:50:10.000Z"},{"name":"a","age":19,"date":"2026-03-13T06:12:30.000Z"},{"name":"b","age":30,"date":"2026-03-09T03:10:40.000Z"}]
            numberSorted.sort(compareByJsonKey('age', { order: 'asc', type: 'number' })); // 작은 순서
            
            console.log('numberSorted : asc : ', JSON.stringify(numberSorted));

            // [{"name":"b","age":30,"date":"2026-03-09T03:10:40.000Z"},{"name":"a","age":19,"date":"2026-03-13T06:12:30.000Z"},{"name":"A","age":12,"date":"2026-03-10T00:50:10.000Z"},{"name":"c","age":10,"date":"2026-03-12T01:32:20.000Z"}]
            numberSorted.sort(compareByJsonKey('age', { order: 'desc', type: 'number' })); // 큰 순서
            
            console.log('numberSorted : desc : ', JSON.stringify(numberSorted));


            // --------------------------------------------
            // ✅ [특정 날짜 기준 : 데이터 정렬 수행]
            // --------------------------------------------
            const dateSorted = JSON.parse(JSON.stringify(origin));

            // [{"name":"b","age":30,"date":"2026-03-09T03:10:40.000Z"},{"name":"A","age":12,"date":"2026-03-10T00:50:10.000Z"},{"name":"c","age":10,"date":"2026-03-12T01:32:20.000Z"},{"name":"a","age":19,"date":"2026-03-13T06:12:30.000Z"}]
            dateSorted.sort(compareByJsonKey('date', { order: 'asc', type: 'date' })); // 작은 순서
            
            console.log('dateSorted : asc : ', JSON.stringify(dateSorted));

            // [{"name":"a","age":19,"date":"2026-03-13T06:12:30.000Z"},{"name":"c","age":10,"date":"2026-03-12T01:32:20.000Z"},{"name":"A","age":12,"date":"2026-03-10T00:50:10.000Z"},{"name":"b","age":30,"date":"2026-03-09T03:10:40.000Z"}]
            dateSorted.sort(compareByJsonKey('date', { order: 'desc', type: 'date' })); // 큰 순서
            
            console.log('dateSorted : desc : ', JSON.stringify(dateSorted));
          }
          catch (exception) {
            console.error("[window onload] : [Exception] : 예외 상황 발생 : ", exception);

          }

        };

    </script>


</head>


<body>

</body>

</html>

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[참고 사이트]
-----------------------------------------------------------------------------------------

[간단 소스] 자바스크립트 Object.keys 사용해 json 에 저장 된 key 키 포함 및 개수 확인 및 for 문 key , value 출력

https://kkh0977.tistory.com/8691

https://blog.naver.com/kkh0977/224214219987


[자바스크립트 json string 문자열 데이터 JSON.parse 사용해 model 객체에 매핑 수행]

https://kkh0977.tistory.com/5055

https://blog.naver.com/kkh0977/223304887680?trackingCode=blog_bloghome_searchlist


[json 특정 key 포함 확인 및 데이터 출력 실시 - hasOwnProperty , for in]

https://kkh0977.tistory.com/1092

https://blog.naver.com/kkh0977/222461468315?trackingCode=blog_bloghome_searchlist


[JsonArray 에 담긴 JsonObject 객체 파싱해 특정 idx (순서) 로 정렬 실시]

https://kkh0977.tistory.com/876

https://blog.naver.com/kkh0977/222399966146?trackingCode=blog_bloghome_searchlist

-----------------------------------------------------------------------------------------
 
728x90
반응형
Comments