반응형

     정보

    • 업무명     : 자바스크립트 JSON 문자열에 대한 다양한 처리 방법

    • 작성자     : 이상호

    • 작성일     : 2020-05-02

    • 설   명      :

    • 수정이력 :

     

     내용

    [개요]

    • 안녕하세요? 웹 개발 및 연구 개발을 담당하고 있는 해솔입니다.

    • 자바스크립트 (Java Script)를 자유롭게 사용하기 위해서는 해결 방법을 기억할 필요가 있습니다.

    • 해결 방법은 어떤 방법으로도 대부분 원하는 결과를 얻을 수 있습니다.

    • 그러나 그 중에서도 단순하고 읽기 쉽고 유용한 해결책은 존재합니다.

    • 오늘 포스팅에서는 자바스크립트 JSON 문자열에 대한 다양한 처리 방법을 소개해 드리고자 합니다.

     

     

    [특징]

    • 웹 개발을 위해서 자바스크립트 (Java Script)기술이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 기술서

     

    [기능]

    • JSON 형식 문자열 자료

    • JSON 자료 처리

    • 제어 구문 해결

    • 배열의 항목 확인

    • 문자열로 처리

    • reduce 이용

    • filter 이용

    • 배열의 새로운 메서드를 사용

     

    [활용 자료]

    • 없음

     

    [자료 처리 방안 및 활용 분석 기법]

    • 없음

     

    [사용법]

    • 없음

     

    [사용 OS]

    • Windows 10

     

    [사용 언어]

    • Java Script

    • Visual Studio Code v1.43.2

     

     세부 내용

    [JSON 형식 문자열 자료]

    • JSON 구조는 다음과 같이 id 및 name은 속성을 가진 객체의 배열이 있습니다.

    • 이러한 JSON 구조를 이해하기 위해서 간단한 시나리오를 진행할 예정입니다.

    • 즉 id에 해당하는 인덱스를 입력할 경우 name를 반환하는  staff 함수를 작성합니다. 만약 해당 id이 있는 사람이없는 경우 null를 표시합니다.

    [
      { "id":1, "name":"홍길동1" },
      { "id":2, "name":"홍길동2" },
      ...
    ]

     

    staff(1); // 홍길동1
    staff(5); // 홍길동2
    staff(999); // null

     

    [JSON 자료 처리]

    • 소스 코드를 실행하면 작동되나 몇가지 문제 존재합니다.

    • 불필요한 처리 존재

      • var dataJson = data.replace(/'/g, "");와 같이 필요한 코드 존재합니다.

      • 이는 원본 데이터에서 전체 치환하여 제거하나 원본 데이터는 ''가 존재하지 않습니다.

    • 배열의 순서에 따라 Name 추출

      • 이 예제 데이터의 경우 우연히 배열 순서와 id 번호가 +1 하는 것만으로 일치합니다.

      • 따라서 문제없이 실행되나 데이터의 id가 없거나 순서가 변경되면 잘못된 데이터가 추출합니다.

      • 즉 배열의 7번째에 있는 사람과 id가 7번 사람은 다르다.

    • 없을 경우 Null 처리

      • 사용자가 없을 경우 null 대신 문자열의 'null'으로 반환합니다.

      • 또한 사용자 요구사항에 따라 문자열로 반환이 올바른 경우도 있으니 주의가 필요합니다.

     

    var dataJson = data.replace(/'/g, "");
    // console.log(dataJson);
    var staffsData = JSON.parse(dataJson);
    // console.log(staff[0].id);
    // console.log(staff.length);
    var staffNumber = staffsData.length;
    
    function staff(id){
        if (id >= 1 && id <= staffNumber){
            console.log(staffsData[id-1].name);
        } else {
            console.log('null');
        }
    }

     

    [제어 구문 해결]

    • 제어 구문을 이용한 코드로 일반적인 방법으로 memo는 임시 변수를 사용 거기에 대응하는 id의 사람이 있으면 임시 저장합니다.

    • 이 경우 memo 변수가 값이 없는 경우 (undefined) 해당 id가 없는 것으로 판단합니다.

    • 문제를 지적하면 memo 변수명이 무엇을 의도하는 지 알기 어렵기 때문에 staffName 변수명과 같은 내용에 맞는 변수명이 좋습니다.

    • 자바스크립트 입문 도서에서도 이러한 방법이 많습니다.

    • for문 및 if문의 조합으로 대부분의 문제는 해결할 수 있으나 복잡한 문제일수록 읽기가 어렵습니다.

     

    var staffData = JSON.parse(data);
    var staffNumber = staffData.length;
    // console.log(staffNumber);
    function staff(id){
        var memo;
        for (var i = 0; i < staffNumber; i++){
        // console.log('id :' + staff[i].id + 'name:' + staff[i].name);
            if ( staffData[i].id === id ){
                console.log(staffData[i].name);
                memo = staffData[i].name;
            } 
        }
        if (memo == undefined){
            console.log('null');
        }
    }

     

    [배열의 항목 확인]

    • JSON을 파싱하고 배열에 some를 사용하고 있습니다. some 인수로 전달된 함수에서 true 또는 false 판정 결과를 반환합니다. 

    • 이것을 사용하여 staff의 인수로 전달된 id가 data에 포함 여부를 판정하고 포함할 경우 이름을 출력합니다.

     

    var staff = function (id) {
      var called = JSON.parse(data).some(function (person) {
      
        if (person.id === id) {
         console.log(person.name);
         return true;
         
        }
      });
      
      if (!called) {
        console.log(null);
      }
    }

     

    [문자열로 처리]

    • 데이터를 JSON.parse 하지 않고 문자열 그대로 처리하고 있습니다.

    • 정규식 부분에서 문자로 id 일치하고 name에 매치한 문자열을 표시하고 있습니다.

    • JSON 데이터의 경우 처리 과정에서 성능 저하는 없으나 HTML의 DOM 조작 성능으로 문제가 되면 문자열로 처리함으로써 개선할 수 있습니다.

    • 또한 판정 결과에 대한 null 처리는 삼항 연산자를 사용하고 있습니다. 이러한 간단한 조건 분기는 삼항 연산자를 사용하면 깔끔하게 쓸 수 있습니다.

     

    function staff(id) {
        var reg = new RegExp('"id":'+id+',"name":"([^"]*)"',"i");
        var match = data.match(reg);
        console.log( match ? match[1] : null );
    };

     

    [reduce 사용]

    • 우선 mapById 객체는 JSON을 파싱하고 배열로부터 reduce를 사용하여 생성합니다. 즉 item 데이터를 누적하여 하나의 값으로 배열을 생성합니다.

    • reduce는 2번째 인자를 지정하면 그 값을 초기 값으로 순서대로 배열 값을 처리해 나갈 수 있습니다. 즉 생성된 객체는 다음과 같은 id를 속성 이름과 객체입니다.

    • 이 경우 staff 함수 내에서 id에 대응하는 데이터를 특정하는 것이 간단합니다.

    • 또한 미리 개체를 생성함으로써 매번 JSON을 구문 분석할 필요가 없기 때문에 그만큼 처리가 가볍게 끝날 것입니다.

     

    var mapById =  JSON.parse(data).reduce(function(map, item) {
      map[item.id] = item;
      return map;
    }, {});
     
    function staff(id) {
      return mapById[id] ? mapById[id].name : null;
    }
     
    console.log(staff(1));

     

    [filter 이용]

    • 배열의 filter는 전달된 함수를 사용하여 조건 판정 (true, false)을 합니다. 즉 filter를 통해 id가 일치하는 항목을 추출하여 1번째를 사용하여 판정을 실시하고 있습니다.

    • 실무에서는 이러한 배열에 대한 조작이있는 경우 Underscore.js를 사용하는 경우가 많습니다.

     

    function staff(id) {
      var person = JSON.parse(data).filter(function(v){
        return v.id === id
      })[0];
      return person ? person.name : null;
    }

     

    • _.findWhere는 조건으로 객체를 전달 일치했지만 1번째를 반환하는 함수입니다.

    • 처리의 흐름은 앞서의 filter를 사용한 경우와 같이 해당하는 사람만 필터링하고 그 결과를 바탕으로 판정합니다.

     

    function staff(id) {
        var person = _.findWhere(JSON.parse(data), {id: id});
        return person ? person.name : null;
    }

     

    [배열의 새로운 메소드를 사용]

    • 이번에 소개한 some, reduce, filter는 IE9 이상에서만 지원하지 않습니다.

    • 따라서 앞서 소개한 Underscore.js에 포함되어있는 _.some, _.reduce, _.filter을 사용하면 오래된 브라우저에도 대응할 수 있습니다.

    • 또한 그 외에도 _.findWhere 같은 배열 작업에 대한 유용한 기능을 사용할 수 있습니다.

     

    function staff(id) {
        var person = _.findWhere(JSON.parse(data), {id: id});
        return person ? person.name : null;
    }

     

     요약

    • 같은 문제도 여러 해결 방법이 있으며 각 방법도 장점과 단점이 존재합니다. 이번에 소개한 방법 이외에도 좋은 해결 방법이 있다고 생각합니다. 

    • 많은 방법을 알기위한 실제 프로그램 중 적절한 방법을 선택할 수 코드를 쓸 수 있습니다. 프로그램을 쓸 사람은 많은 해결 방법 중에서 적절한 방법을 선택합니다.

    • 문제 해결 패턴 (해법)을 많이 알고 있고 이를 구현하는데  조금이라도 도움이 되었으면 좋겠습니다.

     

     참고 문헌

    [논문]

    • 없음

    [보고서]

    • 없음

    [URL]

    • 없음

     

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    본 블로그는 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음
    반응형
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기