2012-02-21 14 views
111

में एक ऑब्जेक्ट (पार्स पेड़) है जिसमें बाल नोड्स हैं जो अन्य नोड्स के संदर्भ हैं।साइक्लिक ऑब्जेक्ट वैल्यू

मैं JSON.stringify() का उपयोग करके इस ऑब्जेक्ट को क्रमबद्ध करना चाहता हूं, लेकिन मुझे बताई गई संरचनाओं के कारण TypeError: cyclic object value मिलता है।

मैं इसके आसपास कैसे काम कर सकता हूं? इससे कोई फर्क नहीं पड़ता कि क्या अन्य नोड्स के इन संदर्भों को धारावाहिक वस्तु में दर्शाया गया है या नहीं।

दूसरी तरफ, इन गुणों को वस्तु से हटाते समय उन्हें थकाऊ लगता है और मैं पार्सर (narcissus) में परिवर्तन नहीं करना चाहता।

+1

हम कुछ कोड के बिना आपकी मदद नहीं कर सकते हैं। कृपया जेएस के साथ अपने ऑब्जेक्ट और/या JSON आउटपुट के प्रासंगिक बिट्स को पोस्ट करें जो आप इसे क्रमबद्ध करने के लिए उपयोग करते हैं। – Bojangles

+1

क्या आप उन गुणों के लिए कुछ उपसर्ग जोड़ सकते हैं जो आंतरिक संदर्भ हैं? – wheresrhys

+0

@ लॉइक डगलस क्रॉकफोर्ड के 'cycle.js' को यहां एक उत्तर के रूप में मूल्यवान होगा, क्योंकि यह कई मामलों के लिए सबसे उपयुक्त समाधान है। यह उत्तर पोस्ट करने के लिए आपके लिए उचित लगता है, क्योंकि आप इसे संदर्भित करने वाले पहले व्यक्ति हैं (नीचे दी गई टिप्पणी में)। यदि आप इसे अपने उत्तर के रूप में पोस्ट करना पसंद नहीं करते हैं, तो मैं अंततः ऐसा करूंगा। –

उत्तर

157

stringify का दूसरा पैरामीटर, replacer function का प्रयोग करें, बाहर करने के लिए पहले से ही धारावाहिक वस्तुओं:

var seen = []; 

JSON.stringify(obj, function(key, val) { 
    if (val != null && typeof val == "object") { 
     if (seen.indexOf(val) >= 0) { 
      return; 
     } 
     seen.push(val); 
    } 
    return val; 
}); 

http://jsfiddle.net/mH6cJ/38/

के रूप में सही ढंग से, इस कोड को हर "देखा" वस्तु, नहीं निकालता है अन्य टिप्पणी में बताया केवल "रिकर्सिव" वाले।

उदाहरण के लिए, के लिए:

a = {x:1}; 
obj = [a, a]; 

परिणाम गलत हो जाएगा। यदि आपकी संरचना इस तरह है, तो क्रॉकफ़ोर्ड का decycle एक बेहतर विकल्प है।

+2

हाँ अच्छा है! धन्यवाद, मैं इसे आजमाने जा रहा हूं। मुझे डगलस क्रॉकफ़ोर्ड (https://github.com/douglascrockford/JSON-js/blob/master/cycle.js) द्वारा निर्मित समाधान मिला, लेकिन जैसा कि मुझे इसके साथ चलने वाले लाइसेंस का अनिश्चितता है, आप जिस आसान समाधान का वर्णन करते हैं सटीक होगा! –

+3

@LoicDuros लाइसेंस "सार्वजनिक डोमेन" है। मतलब, आप जो कुछ भी चाहते हैं वह कर सकते हैं। –

+1

यह कोड साइक्लिंग लूप उत्पन्न करता है, उपयोग करने से सावधान रहें, आपके ऐप को बहुत संभावित क्रैश करता है। सही अर्धविराम की आवश्यकता है और घटना वस्तुओं पर उपयोग नहीं किया जा सकता है! –

1

अधिक सेवर और यह दिखाता है कि चक्र ऑब्जेक्ट था।

<script> 
var jsonify=function(o){ 
    var seen=[]; 
    var jso=JSON.stringify(o, function(k,v){ 
     if (typeof v =='object') { 
      if (!seen.indexOf(v)) { return '__cycle__'; } 
      seen.push(v); 
     } return v; 
    }); 
    return jso; 
}; 
var obj={ 
    g:{ 
     d:[2,5], 
     j:2 
    }, 
    e:10 
}; 
obj.someloopshere = [ 
    obj.g, 
    obj, 
    { a: [ obj.e, obj ] } 
]; 
console.log('jsonify=',jsonify(obj)); 
</script> 

पैदा करता

jsonify = {"g":{"d":[2,5],"j":2},"e":10,"someloopshere":[{"d":[2,5],"j":2},"__cycle__",{"a":[10,"__cycle__"]}]} 
+0

हटा नहीं देना चाहिए, लेकिन अगर कोई व्यक्ति 'obj.b = this''' के साथ ऑब्जेक्ट बनाता है तो इस कोड के साथ अभी भी कोई समस्या है किसी को पता है कि 'यह' के साथ गलत दिए गए दायरे से बने बहुत लंबे कैल्क्स को कैसे रोकें –

+2

यह देखना चाहिए 'देखा.indexOf (v)! = -1' –

2

मैं एक GitHub सार जो डे चक्रीय संरचनाओं पता लगाने में सक्षम है और यह भी है और उन्हें encodes बना लिया है: https://gist.github.com/Hoff97/9842228

बस का उपयोग बदलने के लिए JSONE.stringify/JSONE.parse। यह भी डी- और कार्यों को एन्कोड करता है। यदि आप इसे अक्षम करना चाहते हैं तो बस 32-48 और 61-85 लाइनों को हटा दें।

var strg = JSONE.stringify(cyclicObject); 
var cycObject = JSONE.parse(strg); 

आप एक उदाहरण बेला यहाँ पा सकते हैं:

http://jsfiddle.net/hoff97/7UYd4/

+1

अच्छा है, लेकिन यह तारीख को संभालने वाला नहीं है .. – Seraph

1
function stringifyObject (obj) { 
    if (_.isArray(obj) || !_.isObject(obj)) { 
    return obj.toString() 
    } 
    var seen = []; 
    return JSON.stringify(
    obj, 
    function(key, val) { 
     if (val != null && typeof val == "object") { 
     if (seen.indexOf(val) >= 0) 
      return 
      seen.push(val) 
      } 
     return val 
    } 
); 
} 

एक पूर्व शर्त याद आ रही थी, अन्यथा सरणी वस्तुओं में पूर्णांक मूल्यों, छोटा कर रहे हैं यानी [[2014/11/08 12: 30:13, 10 9 5]] 10 9 5 को घटाकर 0 9 0 कर दिया गया है।

0

मैं भी एक जिथब प्रोजेक्ट बनाता हूं जो चक्रीय वस्तु को क्रमबद्ध कर सकता है और कक्षा को बहाल कर सकता है यदि आप इसे धारावाहिक में सहेजते हैं नाम एक स्ट्रिंग की तरह विशेषता

var d={} 
var a = {b:25,c:6,enfant:d}; 
d.papa=a; 
var b = serializeObjet(a); 
assert.equal( b, "{0:{b:25,c:6,enfant:'tab[1]'},1:{papa:'tab[0]'}}"); 
var retCaseDep = parseChaine(b) 
assert.equal( retCaseDep.b, 25); 
assert.equal( retCaseDep.enfant.papa, retCaseDep); 

https://github.com/bormat/serializeStringifyParseCyclicObject

संपादित करें: मैं NPM https://github.com/bormat/borto_circular_serialize के लिए मेरी स्क्रिप्ट को बदलने और मैं से फ्रेंच अंग्रेज़ी में बदलें समारोह नाम है।

+0

यह उदाहरण गिस्ट फिट नहीं है। गस्ट में त्रुटियां हैं। –

+0

अच्छा विचार - लेकिन एक बार इसे तैयार करने के लिए :-) यदि आप इसे एनपीएम में वितरित कर देंगे, तो शायद आप इसके लिए भी टाइपिंग विकसित करेंगे, यह शायद काफी लोकप्रिय हो गया है। – peterh

+0

हाँ, अच्छा विचार। – bormat