JSON 문자열화 깊이 제한
개체를 문자열화할 때JSON.stringify
(또는 이와 유사한 것) 문자열화의 깊이를 제한하는 방법이 있습니까?즉, 오브젝트 트리의 깊이에 n개의 레벨만 들어가 그 이후의 모든 것을 무시하는 것이 좋습니다(또는 플레이스 홀더를 그 안에 배치하여 뭔가 누락되었음을 나타냄).
나는 그것을 알고 있습니다.JSON.stringify
형식의 리페이서 함수를 사용합니다.function (key, value)
그러나 리페이서 함수에 전달된 현재 키-값-쌍의 원래 객체의 깊이를 얻을 수 있는 방법을 찾지 못했습니다.
디폴트 JSON.stringify 실장에서는 이 방법을 사용할 수 있습니까?아니면 제가 직접 스트링라이제이션(stringization)을 구현해야 할 지경에 이르렀나요?또는 이 옵션이 있는 다른 문자열화 라이브러리가 있습니까?
서드파티 라이브러리를 포함하지 않고 첫 번째 레벨에서 오브젝트를 문자열화하려고 했습니다/너무 많은 코드를 포함시키지 않았습니다.
같은 것을 찾고 있는 경우는, 다음의 간단한 원라이너를 참조해 주세요.
var json = JSON.stringify(obj, function (k, v) { return k && v && typeof v !== "number" ? (Array.isArray(v) ? "[object Array]" : "" + v) : v; });
최상위 개체에는 키가 없으므로 항상 단순하게 반환되지만 다음 단계의 "숫자"가 아닌 개체는 어레이의 특수한 경우를 포함하여 문자열에 할당됩니다. 그렇지 않으면 더 많이 노출됩니다.
이 특수한 어레이 케이스가 마음에 들지 않는 경우는, 저도 개선한 낡은 솔루션을 사용해 주세요.
var json = JSON.stringify(obj, function (k, v) { return k && v && typeof v !== "number" ? "" + v : v; }); // will expose arrays as strings.
그래도 상위 레벨의 개체 대신 어레이를 전달하면 두 솔루션 모두 작동합니다.
예:
var obj = {
keyA: "test",
keyB: undefined,
keyC: 42,
keyD: [12, "test123", undefined]
}
obj.keyD.push(obj);
obj.keyE = obj;
var arr = [12, "test123", undefined];
arr.push(arr);
var f = function (k, v) { return k && v && typeof v !== "number" ? (Array.isArray(v) ? "[object Array]" : "" + v) : v; };
var f2 = function (k, v) { return k && v && typeof v !== "number" ? "" + v : v; };
console.log("object:", JSON.stringify(obj, f));
console.log("array:", JSON.stringify(arr, f));
console.log("");
console.log("with array string cast, so the array gets exposed:");
console.log("object:", JSON.stringify(obj, f2));
console.log("array:", JSON.stringify(arr, f2));
여기 빌트인을 존중하는 기능이 있습니다.JSON.stringify()
룰과 깊이를 제한합니다.
function stringify(val, depth, replacer, space) {
depth = isNaN(+depth) ? 1 : depth;
function _build(key, val, depth, o, a) { // (JSON.stringify() has it's own rules, which we respect here by using it for property iteration)
return !val || typeof val != 'object' ? val : (a=Array.isArray(val), JSON.stringify(val, function(k,v){ if (a || depth > 0) { if (replacer) v=replacer(k,v); if (!k) return (a=Array.isArray(v),val=v); !o && (o=a?[]:{}); o[k] = _build(k, v, a?depth:depth-1); } }), o||(a?[]:{}));
}
return JSON.stringify(_build('', val, depth), null, space);
}
구조:
_build()
를 재귀적으로 호출하여 요청된 깊이까지 중첩된 개체와 배열을 빌드합니다.JSON.stringify()
기본 제공 규칙을 준수하기 위해 각 개체의 직접 속성을 반복하기 위해 사용합니다.'undefined'는 항상 내부 리페이서로부터 반환되므로 JSON은 아직 실제로 구축되지 않았습니다.내부 리페이서가 처음 호출될 때 키가 비어 있습니다(문자열화할 항목).JSON.stringify()
실제 JSON을 생성하기 위해 최종 결과를 호출합니다.
예:
var value={a:[12,2,{y:3,z:{q:1}}],s:'!',o:{x:1,o2:{y:1}}};
console.log(stringify(value, 0, null, 2));
console.log(stringify(value, 1, null, 2));
console.log(stringify(value, 2, null, 2));
{}
{
"a": [
12,
2,
{}
],
"s": "!",
"o": {}
}
{
"a": [
12,
2,
{
"y": 3,
"z": {}
}
],
"s": "!",
"o": {
"x": 1,
"o2": {}
}
}
(순환 참조를 처리하는 버전에 대해서는, 여기를 참조해 주세요.https://stackoverflow.com/a/57193345/1236397 - TypeScript 버전 포함)
업데이트: 빈 배열이 빈 개체로 렌더링되는 오류를 수정했습니다.
오브젝트의 딥 클론(라이브러리(로우대시 등)을 작성하고 원하는 프루닝을 수행한 후 JSON.stringify로 전달합니다.JSON.stringify를 재발명하려고 하지 않습니다.그것은 잘못된 장소에서의 노력입니다.
[EDIT]는 이미 다른 사용자가 제안한 대로 한 것 같습니다.JSON.stringize deep objects
네이티브 JSON.stringify는 항상 더 빠르고 강력하기 때문에 권장하지 않습니다.
[편집] 원하는 기능을 할 수 있는 라이브러리입니다.http://philogb.github.io/jit/static/v20/Docs/files/Core/Core-js.html#$jit.json.prune
언급URL : https://stackoverflow.com/questions/16466220/limit-json-stringification-depth
'source' 카테고리의 다른 글
교차 도메인 AJAX가 X-Requested-With 헤더를 전송하지 않음 (0) | 2023.03.23 |
---|---|
AngularJs의 $evalAsync와 $timeout의 차이점은 무엇입니까? (0) | 2023.03.23 |
스프링 부트에 포함된 Tomcat 버전을 확인하는 방법 (0) | 2023.03.23 |
WooCommerce에서 카트가 비어있는 경우에도 URL에서 GET 방식으로 쿠폰 할인 적용 (0) | 2023.03.23 |
margin-top 삭제 방법: 32px!중요한 것은 12부터입니다. (0) | 2023.03.23 |