복붙노트

[JQUERY] JSON 개체에서 순환 참조 해결

JQUERY

JSON 개체에서 순환 참조 해결

해결법


  1. 1.서버에서 수신 된 JSON 객체는 순환 참조가 포함되어 있습니다. 객체를 사용하기 전에 당신이 $ 심판의 자리에 먼저 제거하려면 모든 $ 심판의 객체에서 속성 수단을 가져야한다 : "1"당신은 목적이 링크 점을 넣어해야합니다.

    서버에서 수신 된 JSON 객체는 순환 참조가 포함되어 있습니다. 객체를 사용하기 전에 당신이 $ 심판의 자리에 먼저 제거하려면 모든 $ 심판의 객체에서 속성 수단을 가져야한다 : "1"당신은 목적이 링크 점을 넣어해야합니다.

    귀하의 경우가있을 수 있습니다 그것은 id가 1 인 사용자의 객체를 가리키는

    github.There에 더글러스 Crockfords 플러그인 당신을 위해 일을 할 수있는 cycle.js를 체크 아웃이를 위해 당신은 확인해야합니다.

    또는 다음 코드를 (테스트하지)를 사용할 수 있습니다 :

    function resolveReferences(json) {
        if (typeof json === 'string')
            json = JSON.parse(json);
    
        var byid = {}, // all objects by id
            refs = []; // references to objects that could not be resolved
        json = (function recurse(obj, prop, parent) {
            if (typeof obj !== 'object' || !obj) // a primitive value
                return obj;
            if ("$ref" in obj) { // a reference
                var ref = obj.$ref;
                if (ref in byid)
                    return byid[ref];
                // else we have to make it lazy:
                refs.push([parent, prop, ref]);
                return;
            } else if ("$id" in obj) {
                var id = obj.$id;
                delete obj.$id;
                if ("$values" in obj) // an array
                    obj = obj.$values.map(recurse);
                else // a plain object
                    for (var prop in obj)
                        obj[prop] = recurse(obj[prop], prop, obj)
                byid[id] = obj;
            }
            return obj;
        })(json); // run it!
    
        for (var i=0; i<refs.length; i++) { // resolve previously unknown references
            var ref = refs[i];
            ref[0][ref[1]] = byid[refs[2]];
            // Notice that this throws if you put in a reference at top-level
        }
        return json;
    }  
    

    도움이된다면 알려주세요!


  2. 2.나는 몇 가지 버그를 발견하고 구현 배열 지원 :

    나는 몇 가지 버그를 발견하고 구현 배열 지원 :

    function resolveReferences(json) {
        if (typeof json === 'string')
            json = JSON.parse(json);
    
        var byid = {}, // all objects by id
            refs = []; // references to objects that could not be resolved
        json = (function recurse(obj, prop, parent) {
            if (typeof obj !== 'object' || !obj) // a primitive value
                return obj;
            if (Object.prototype.toString.call(obj) === '[object Array]') {
                for (var i = 0; i < obj.length; i++)
                    // check also if the array element is not a primitive value
                    if (typeof obj[i] !== 'object' || !obj[i]) // a primitive value
                        continue;
                    else if ("$ref" in obj[i])
                        obj[i] = recurse(obj[i], i, obj);
                    else
                        obj[i] = recurse(obj[i], prop, obj);
                return obj;
            }
            if ("$ref" in obj) { // a reference
                var ref = obj.$ref;
                if (ref in byid)
                    return byid[ref];
                // else we have to make it lazy:
                refs.push([parent, prop, ref]);
                return;
            } else if ("$id" in obj) {
                var id = obj.$id;
                delete obj.$id;
                if ("$values" in obj) // an array
                    obj = obj.$values.map(recurse);
                else // a plain object
                    for (var prop in obj)
                        obj[prop] = recurse(obj[prop], prop, obj);
                byid[id] = obj;
            }
            return obj;
        })(json); // run it!
    
        for (var i = 0; i < refs.length; i++) { // resolve previously unknown references
            var ref = refs[i];
            ref[0][ref[1]] = byid[ref[2]];
            // Notice that this throws if you put in a reference at top-level
        }
        return json;
    }
    

  3. 3.당신이 JSON.parse의 자극성 매개 변수를 활용하면 이것은 실제로 매우 간단합니다.

    당신이 JSON.parse의 자극성 매개 변수를 활용하면 이것은 실제로 매우 간단합니다.

    예 아래. StackOverflow의의 조각 콘솔 출력 결과가 무엇인지에 대한 정확한 그림을 제공하지 않기 때문에 출력을위한 브라우저 콘솔을 참조하십시오.

    // 예를 들어, JSON var에 J = '{ "$ ID": "0", "이름": "부모", "아이": { "$ ID": "1", "이름": "아이", "부모": { " $ REF ":"0 "}}"에 nullValue ": NULL} ' 함수 parseAndResolve JSON () { VAR refMap = {}; 창 JSON.parse JSON (함수 (키 값) { 경우 (키 === '$ 아이디') { refMap [값이 =; // 반환 속성이 ​​삭제되도록 정의되지 않은 리턴 공극 (0); } 경우 (값 && 값 $ REF.) {리턴 refMap [$ 값 REF.]; } 값을 반환; }); } CONSOLE.LOG (parseAndResolve (j));


  4. 4.나는 알렉산더 바실리에 브의 대답에 배열 수정에 문제가 있었다.

    나는 알렉산더 바실리에 브의 대답에 배열 수정에 문제가 있었다.

    나는 새로운 답을 추가했다, 그래서 나는 그의 대답을 말씀 드릴 수 없습니다, (;-)하지 자신의 충분한 명성 포인트를 할) ... (여기서에게 나는 가장 좋은 방법은 없습니다 다른 답변에 대답에 만 원래의 질문에 팝업을했다 - BOF)

        if (Object.prototype.toString.call(obj) === '[object Array]') {
            for (var i = 0; i < obj.length; i++) {
                // check also if the array element is not a primitive value
                if (typeof obj[i] !== 'object' || !obj[i]) // a primitive value
                    return obj[i];
                if ("$ref" in obj[i])
                    obj[i] = recurse(obj[i], i, obj);
                else
                    obj[i] = recurse(obj[i], prop, obj);
            }
            return obj;
        }
    

  5. 5.당신이 배열을 검사하고, 원시 값 건너있는 경우 허용 구현에서 해당 값을 반환하고 배열을 덮어 쓰게됩니다. 대신 배열의 모든 요소를 ​​검사 계속 끝의 배열을 반환합니다.

    당신이 배열을 검사하고, 원시 값 건너있는 경우 허용 구현에서 해당 값을 반환하고 배열을 덮어 쓰게됩니다. 대신 배열의 모든 요소를 ​​검사 계속 끝의 배열을 반환합니다.

    function resolveReferences(json) {
        if (typeof json === 'string')
            json = JSON.parse(json);
    
        var byid = {}, // all objects by id
            refs = []; // references to objects that could not be resolved
        json = (function recurse(obj, prop, parent) {
            if (typeof obj !== 'object' || !obj) // a primitive value
                return obj;
            if (Object.prototype.toString.call(obj) === '[object Array]') {
                for (var i = 0; i < obj.length; i++)
                    // check also if the array element is not a primitive value
                    if (typeof obj[i] !== 'object' || !obj[i]) // a primitive value
                        continue;
                    else if ("$ref" in obj[i])
                        obj[i] = recurse(obj[i], i, obj);
                    else
                        obj[i] = recurse(obj[i], prop, obj);
                return obj;
            }
            if ("$ref" in obj) { // a reference
                var ref = obj.$ref;
                if (ref in byid)
                    return byid[ref];
                // else we have to make it lazy:
                refs.push([parent, prop, ref]);
                return;
            } else if ("$id" in obj) {
                var id = obj.$id;
                delete obj.$id;
                if ("$values" in obj) // an array
                    obj = obj.$values.map(recurse);
                else // a plain object
                    for (var prop in obj)
                        obj[prop] = recurse(obj[prop], prop, obj);
                byid[id] = obj;
            }
            return obj;
        })(json); // run it!
    
        for (var i = 0; i < refs.length; i++) { // resolve previously unknown references
            var ref = refs[i];
            ref[0][ref[1]] = byid[ref[2]];
            // Notice that this throws if you put in a reference at top-level
        }
        return json;
    }
    

  6. 6.내 솔루션 (물론 배열 작품) :

    내 솔루션 (물론 배열 작품) :

    사용 : rebuildJsonDotNetObj (jsonDotNetResponse)

    코드:

    function rebuildJsonDotNetObj(obj) {
        var arr = [];
        buildRefArray(obj, arr);
        return setReferences(obj, arr)
    }
    
    function buildRefArray(obj, arr) {
        if (!obj || obj['$ref'])
            return;
        var objId = obj['$id'];
        if (!objId)
        {
            obj['$id'] = "x";
            return;
        }
        var id = parseInt(objId);
        var array = obj['$values'];
        if (array && Array.isArray(array)) {
            arr[id] = array;
            array.forEach(function (elem) {
                if (typeof elem === "object")
                    buildRefArray(elem, arr);
            });
        }
        else {
            arr[id] = obj;
            for (var prop in obj) {
                if (typeof obj[prop] === "object") {
                    buildRefArray(obj[prop], arr);
                }
            }
        }
    }
    
    function setReferences(obj, arrRefs) {
        if (!obj)
            return obj;
        var ref = obj['$ref'];
        if (ref)
            return arrRefs[parseInt(ref)];
    
        if (!obj['$id']) //already visited
            return obj;
    
        var array = obj['$values'];
        if (array && Array.isArray(array)) {
            for (var i = 0; i < array.length; ++i)
                array[i] = setReferences(array[i], arrRefs)
            return array;
        }
        for (var prop in obj)
            if (typeof obj[prop] === "object")
                obj[prop] = setReferences(obj[prop], arrRefs)
        delete obj['$id'];
        return obj;
    }
    
  7. from https://stackoverflow.com/questions/15312529/resolve-circular-references-from-json-object by cc-by-sa and MIT license