আমি কীভাবে কোনও JSON- জাতীয় বিন্যাসে একটি বিজ্ঞপ্তি কাঠামো মুদ্রণ করতে পারি?


680

আমার কাছে একটি বড় অবজেক্ট আছে আমি জেএসএন এ রূপান্তর করতে এবং পাঠাতে চাই। তবে এটির বিজ্ঞপ্তি কাঠামো রয়েছে। আমি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সের যে কোনও কিছুই টস করতে চাই এবং যা যা স্ট্রিংফাইন্ড করা যায় তা প্রেরণ করতে চাই। আমি কেমন করে ঐটি করি?

ধন্যবাদ।

var obj = {
  a: "foo",
  b: obj
}

আমি এতে আপত্তিটি আরও শক্তিশালী করতে চাই:

{"a":"foo"}

5
আপনি দয়া করে একটি বিজ্ঞপ্তি রেফারেন্স সহ কোনও নমুনা পোস্ট করতে পারেন যা আপনি পার্স করতে চান?
টিকিউজ

3
ভালো কিছু এই ?
অ্যালভিন ওয়াং


2
পার্টিতে দেরীতে হলেও এটি পরিচালনা করার জন্য একটি গিথুব প্রকল্প রয়েছে।
প্রেস্টন এস

ঘনিষ্ঠভাবে সম্পর্কিত প্রশ্ন: stackoverflow.com/questions/23117470/...
mathheadinclouds

উত্তর:


605

JSON.stringifyএকটি কাস্টম replacer সঙ্গে ব্যবহার করুন । উদাহরণ স্বরূপ:

// Demo: Circular reference
var circ = {};
circ.circ = circ;

// Note: cache should not be re-used by repeated calls to JSON.stringify.
var cache = [];
JSON.stringify(circ, (key, value) => {
  if (typeof value === 'object' && value !== null) {
    // Duplicate reference found, discard key
    if (cache.includes(value)) return;

    // Store value in our collection
    cache.push(value);
  }
  return value;
});
cache = null; // Enable garbage collection

এই উদাহরণে প্রতিস্থাপনকারীটি 100% সঠিক নয় (আপনার "নকল" এর সংজ্ঞা অনুসারে)। নিম্নলিখিত ক্ষেত্রে, একটি মান বাতিল করা হয়:

var a = {b:1}
var o = {};
o.one = a;
o.two = a;
// one and two point to the same object, but two is discarded:
JSON.stringify(o, ...);

তবে ধারণাটি দাঁড়িয়েছে: একটি কাস্টম রিপ্লেজার ব্যবহার করুন এবং পার্সড বস্তুর মানগুলি ট্র্যাক করুন।

এস আই লিখিত একটি ইউটিলিটি ফাংশন হিসাবে:

// safely handles circular references
JSON.safeStringify = (obj, indent = 2) => {
  let cache = [];
  const retVal = JSON.stringify(
    obj,
    (key, value) =>
      typeof value === "object" && value !== null
        ? cache.includes(value)
          ? undefined // Duplicate reference found, discard key
          : cache.push(value) && value // Store value in our collection
        : value,
    indent
  );
  cache = null;
  return retVal;
};

// Example:
console.log('options', JSON.safeStringify(options))

1
@ হ্যারি বাগ কি? আমি খুশির সাথে উত্তরটি ঠিক করব, যদি এতে কোনও ভুল থাকে।
রব ডাব্লু

1
@ ক্রুজডিবাবল সিরিয়ালাইজিং ডম সাধারণত অর্থহীন। তবে, আপনি যদি নিজের উদ্দেশ্যগুলির জন্য অর্থপূর্ণ সিরিয়ালাইজেশন পদ্ধতিটি ভাবতে পারেন, তবে আপনি Node.prototype.toJSON = function() { return 'whatever you think that is right'; };ডিওএম অবজেক্টগুলিতে একটি কাস্টম সিরিয়ালযুক্ত যুক্ত করার চেষ্টা করতে পারেন: (আপনি যদি আরও সাধারণ / নির্দিষ্ট কিছু চান তবে প্রোটোটাইপ ট্রি-তে কিছু চেষ্টা করুন: এইচটিএমএল ডিভিলেট এলটিএইচএমলেমিটমেন্ট প্রয়োগ করে এলিমেন্ট প্রয়োগ নোড ইভেন্টট্রেট প্রয়োগ করে; দ্রষ্টব্য: এটি ব্রাউজার-নির্ভর হতে পারে, আগের গাছটি ক্রোমের জন্য সত্য)
রব ডব্লু

7
এটি ভুল কারণ এটি প্রকৃত চক্রীয় কাঠামোতে না থাকলেও এটি দু'বার অন্তর্ভুক্ত থাকা সামগ্রীর দ্বিতীয় উপস্থিতি এড়িয়ে যাবে। var a={id:1}; JSON.stringify([a,a]);
ব্যবহারকারী2451227

3
@ user2451227 "এই উদাহরণে রিপ্ল্লেয়ারটি 100% সঠিক নয় (আপনার" নকল "এর সংজ্ঞা অনুসারে)) তবে ধারণাটি দাঁড়িয়েছে: একটি কাস্টম রিপ্লেজার ব্যবহার করুন, এবং পার্সড অবজেক্টের মানগুলি ট্র্যাক করুন" "
রব ডাব্লু

4
এখানে জিসির উদ্বেগ তর্কসাপেক্ষভাবে নিষ্প্রয়োজনীয়। এটি যদি একটি একক স্ক্রিপ্ট হিসাবে চালানো হয় তবে স্ক্রিপ্টটি অবিলম্বে বন্ধ হয়ে যায়। যদি এটি বাস্তবায়নের জন্য কোনও ফাংশনের অভ্যন্তরে আবদ্ধ হয় তবে cache
অ্যাক্সেসযোগ্য

704

নোড.জেএস-এ আপনি Use.inspect (অবজেক্ট) ব্যবহার করতে পারেন । এটি স্বয়ংক্রিয়ভাবে "[বিজ্ঞপ্তি]" এর সাথে বিজ্ঞপ্তিযুক্ত লিঙ্কগুলি প্রতিস্থাপন করে।


বিল্ট ইন থাকা সত্ত্বেও (কোনও ইনস্টলেশনের প্রয়োজন নেই) , আপনাকে অবশ্যই এটি আমদানি করতে হবে

import * as util from 'util' // has no default export
import { inspect } from 'util' // or directly
// or 
var util = require('util')
এটি ব্যবহার করতে, কেবল কল করুন
console.log(util.inspect(myObject))

এছাড়াও সচেতন হন যে আপনি পরিদর্শন করতে বিকল্প বিকল্পগুলি পাস করতে পারেন (উপরের লিঙ্কটি দেখুন)

inspect(myObject[, options: {showHidden, depth, colors, showProxy, ...moreOptions}])



দয়া করে নীচে মন্তব্যকারীদের পড়ুন এবং পড়ুন ...


134
ব্যবহারটি একটি অন্তর্নির্মিত মডিউল, আপনাকে এটি ইনস্টল করতে হবে না।
মিটার

10
কনসোল.লগ (Use.inspect (اعتراض))
স্টারসিনমিপকেট

19
@ মিটার এটি অন্তর্নির্মিত, তবে আপনাকে এখনও মডিউলটি লোড করতে হবেvar util = require('util');
বোডেকার

14
আমার মতো obj_str = util.inspect(thing)garbage_str = JSON.stringify(util.inspect(thing))
ঘন হয়ে উঠবেন

7
এটি চেক করার ধরণের সাথে আশেপাশের তুলনায় অনেক ভাল। কেন স্ট্রিংফাইস ঠিক এভাবে কাজ করতে পারে না? যদি এটি জেনে থাকে যে একটি বিজ্ঞপ্তিযুক্ত রেফারেন্স রয়েছে, তবে কেন এটি এড়িয়ে যাওয়ার কথা বলা যায় না ???
ক্রিস ময়ূর 14

141

আমি অবাক হয়েছি কেন এখনও কেউ এমডিএন পৃষ্ঠা থেকে সঠিক সমাধান পোস্ট করেনি ...

const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    return value;
  };
};

JSON.stringify(circularReference, getCircularReplacer());

দেখা মান সঞ্চিত করা উচিত একটি সেটের , অ্যারের মধ্যে না (replacer নামক পরার যে উপাদান ) এবং চেষ্টা করতে কোন প্রয়োজন নেই JSON.stringify প্রতিটি উপাদান শৃঙ্খল একটি চক্রকার রেফারেন্স নেতৃস্থানীয় হবে।

গৃহীত উত্তরের মতো, এই সমাধানটি কেবলমাত্র বিজ্ঞপ্তিগুলি নয়, সমস্ত পুনরাবৃত্তি মান সরিয়ে দেয় । তবে কমপক্ষে এটি ক্ষতিকারক জটিলতা নেই।


ঝরঝরে, তবে এটি কেবল ES2015। কোন সমর্থন নেই।
মার্টিন ক্যাপোডিসি

43
ইয়োদা বলেছেন: "এখনও যদি আইই সমর্থন করে তবে একটি ট্রান্সপ্লেলার ব্যবহার করা উচিত" "
স্পেন ট্রেন

1
replacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; } () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); … JSON.stringify({a:1, b: '2'}, replacer)undefinedক্রোমে ফিরে আসে
রবার্তো টমস

1
এটি প্রতিক্রিয়া + টাইপস্ক্রিপ্টে কাজ করে। ধন্যবাদ
ব্যবহারকারী 3417479

76

শুধু কর

npm i --save circular-json

তারপরে আপনার জেএস ফাইলে

const CircularJSON = require('circular-json');
...
const json = CircularJSON.stringify(obj);

https://github.com/WebReflection/circular-json

দ্রষ্টব্য: এই প্যাকেজটির সাথে আমার কিছু করার নেই। তবে আমি এটির জন্য এটি ব্যবহার করি।

আপডেট 2020

দয়া করে নোট করুন যে সার্কুলার জেএসএন কেবল রক্ষণাবেক্ষণে রয়েছে এবং এর উত্তরাধিকারীর সমতল


অনেক ধন্যবাদ! দুর্দান্ত গ্রন্থাগার, অনেক সময় সাশ্রয় হয়েছে। অতি ক্ষুদ্র (মাত্র 1.4KB মিনিটেড)
ব্রায়ান হক

16
আমি মনে করি আপনার "জাস্ট ডু" এর চেয়ে কোনও মডিউল ব্যবহারের জন্য আরও কিছু ন্যায়সঙ্গততার প্রয়োজন হতে পারে। এবং JSONনীতিতে ওভাররাইট করা দুর্দান্ত নয় ।
এডউইন

স্টাব টেস্টিংয়ের জন্য আমার কোনও জিনিসটি অনুলিপি করা দরকার। এই উত্তর নিখুঁত ছিল। আমি বস্তুটি অনুলিপি করেছি এবং তারপরে ওভাররাইডটি সরিয়েছি। ধন্যবাদ !!
ক্রিস শার্প

1
লেখকের মতে, এই প্যাকেজটি অবচয় করা হয়েছে। বিজ্ঞপ্তি জেএসওএন কেবল রক্ষণাবেক্ষণে রয়েছে, সমতল এটির উত্তরসূরি। লিঙ্ক: github.com/WebReflection/flatted#flatted
রবার্ট মোলিনা

3
সাবধান, 'ফ্ল্যাটেড' (এবং বিজ্ঞপ্তি-জসন?) প্যাকেজটি JSON.stringify () কার্যকারিতাটির প্রতিরূপ দেয় না। এটি নিজস্ব নন- JSON ফর্ম্যাট তৈরি করে। (উদাহরণস্বরূপ, Flatted.stringify({blah: 1})ফলাফলগুলি [{"blah":1}]) আমি দেখতে পাচ্ছি যে কেউ এ সম্পর্কে একটি সমস্যা উত্থাপন করার চেষ্টা করেছিল, এবং লেখক তাদের বেয়াদবি দিয়েছে এবং বিষয়টি মন্তব্যে লক করেছেন।
জামেসলল

48

আমি সত্যই ত্রিঞ্জাজের সমাধানটি পছন্দ করেছি - আরও ভার্বোজ, তবে এতে কিছু বাগ রয়েছে। আমি এগুলি স্থির করেছি যার পক্ষে এটি খুব ভাল লাগে।

এছাড়াও, আমি আমার ক্যাশে অবজেক্টগুলিতে দৈর্ঘ্যের সীমা যুক্ত করেছি।

আমি যে জিনিসটি মুদ্রণ করছি তা যদি সত্যিই বড় হয় - তবে আমি অর্থ অসীম বড় - আমি আমার অ্যালগরিদম সীমাবদ্ধ করতে চাই।

JSON.stringifyOnce = function(obj, replacer, indent){
    var printedObjects = [];
    var printedObjectKeys = [];

    function printOnceReplacer(key, value){
        if ( printedObjects.length > 2000){ // browsers will not print more than 20K, I don't see the point to allow 2K.. algorithm will not be fast anyway if we have too many objects
        return 'object too long';
        }
        var printedObjIndex = false;
        printedObjects.forEach(function(obj, index){
            if(obj===value){
                printedObjIndex = index;
            }
        });

        if ( key == ''){ //root element
             printedObjects.push(obj);
            printedObjectKeys.push("root");
             return value;
        }

        else if(printedObjIndex+"" != "false" && typeof(value)=="object"){
            if ( printedObjectKeys[printedObjIndex] == "root"){
                return "(pointer to root)";
            }else{
                return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase()  : typeof(value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";
            }
        }else{

            var qualifiedKey = key || "(empty key)";
            printedObjects.push(value);
            printedObjectKeys.push(qualifiedKey);
            if(replacer){
                return replacer(key, value);
            }else{
                return value;
            }
        }
    }
    return JSON.stringify(obj, printOnceReplacer, indent);
};

আপনি এই লাইনে একটি নাল চেক মিস করছেন: ফিরে "(দেখুন" + (!! মান। ")";
ইসাক

আমি আনন্দের সাথে এটি যোগ করা হবে। আমি এখুনি যে কোনও সমস্যার মুখোমুখি হয়েছি তাই কেবল কী জেনে রাখা যায় তা আমাকে জানান।
লোক মোগ্রাবি

2
// ব্রাউজারগুলি 20 কে-র বেশি মুদ্রণ করবে না - তবে আপনি সীমা 2k হিসাবে রেখেছেন। ভবিষ্যতের জন্য সম্ভবত পরিবর্তন?
পোচেন

38

@ রবডাব্লু এর উত্তর সঠিক, তবে এটি আরও পারফরম্যান্ট! কারণ এটি হ্যাশম্যাপ / সেট ব্যবহার করে:

const customStringify = function (v) {
  const cache = new Set();
  return JSON.stringify(v, function (key, value) {
    if (typeof value === 'object' && value !== null) {
      if (cache.has(value)) {
        // Circular reference found
        try {
          // If this value does not reference a parent it can be deduped
         return JSON.parse(JSON.stringify(value));
        }
        catch (err) {
          // discard key if value cannot be deduped
         return;
        }
      }
      // Store value in our set
      cache.add(value);
    }
    return value;
  });
};

বিজ্ঞপ্তিযুক্ত রেফারেন্স সহ গভীরভাবে বাসাযুক্ত বস্তুর জন্য স্ট্রিংফাইডডিপ => গিথুব
আলেকজান্ডার মিলস

এটি সম্ভবত যে সেট বাস্তবায়ন হুডের নীচে কেবল একটি অ্যারে এবং সূচিপত্র ব্যবহার করে তবে আমি এটি নিশ্চিত করে নি।
আলেকজান্ডার মিলস

এটি বিভিন্ন মান সহ শিশু {"a":{"b":{"a":"d"}}}
সন্দীপ পিংল

আপনি কি সেই সন্দীপের উদাহরণ দেখাতে পারেন? একটি gist.github.com বা হোয়াট নোট তৈরি করুন
আলেকজান্ডার মিলস

দুর্দান্ত !!! প্রথমে (উপরে থেকে, তবে কেবল 2-3 ফাংশন সমাধানগুলি পরীক্ষা করা হয়েছে) এখানে নোড.জেএস এবং ফিশন ;-) এর অধীনে ওয়ার্কিং সলিউশন - লাইব্রেরিগুলিকে ফাঁসি দেওয়া হয়েছে।
টম

37

দ্রষ্টব্য যে JSON.decycleডগলাস ক্রকফোর্ড দ্বারা প্রয়োগকৃত একটি পদ্ধতিও রয়েছে। তার চক্রJs দেখুন । এটি আপনাকে প্রায় কোনও স্ট্যান্ডার্ড কাঠামো স্ট্রিংফাই করতে দেয়:

var a = [];
a[0] = a;
a[1] = 123;
console.log(JSON.stringify(JSON.decycle(a)));
// result: '[{"$ref":"$"},123]'.

আপনি retrocycleপদ্ধতি সহ মূল বস্তুটি পুনরায় তৈরি করতে পারেন । সুতরাং আপনাকে স্ট্রিংফাইজ করার জন্য অবজেক্ট থেকে চক্র সরিয়ে ফেলতে হবে না।

তবে এটি ডিওএম নোডের জন্য কাজ করবে না (যা বাস্তব জীবনের ব্যবহারের ক্ষেত্রে চক্রের সাধারণ কারণ)। উদাহরণস্বরূপ এটি নিক্ষেপ করবে:

var a = [document.body];
console.log(JSON.stringify(JSON.decycle(a)));

আমি এই সমস্যাটি সমাধান করার জন্য একটি কাঁটাচামচ তৈরি করেছি (আমার চক্র .js কাঁটাচামচ দেখুন )। এটি ভাল কাজ করা উচিত:

var a = [document.body];
console.log(JSON.stringify(JSON.decycle(a, true)));

মনে রাখবেন যে আমার কাঁটাচামুতে JSON.decycle(variable)মূল হিসাবে কাজ করে এবং যখন ব্যতিক্রম হয় তখন নিক্ষেপ করবেvariable এতে ডোম নোড / উপাদান থাকবে।

আপনি যখন ব্যবহার করবেন তখন JSON.decycle(variable, true)এই ফলাফলটি গ্রহণ করুন যে ফলাফলটি বিপরীতমুখী হবে না (রেট্রোসাইকেলটি ডোম নোডগুলি পুনরায় তৈরি করবে না)। DOM উপাদানগুলি কিছুটা হলেও চিহ্নিতযোগ্য হওয়া উচিত। উদাহরণস্বরূপ যদি কোনও divউপাদানের আইডি থাকে তবে এটি স্ট্রিংয়ের সাথে প্রতিস্থাপিত হবে "div#id-of-the-element"


2
আমি যখন সেগুলি ব্যবহার করি তখন তার কোড এবং আপনার উভয়ই আমাকে একটি "রেঞ্জেরর: সর্বোচ্চ কল স্ট্যাকের আকার ছাড়িয়ে গেছে" দেয়।
jcollum

: আমি একটি চেহারা আছে যদি আপনি বেহালার আপনার কোড প্রদান বা GitHub থেকে একটি বিষয় যোগ github.com/Eccenux/JSON-js/issues
Nux

এই আমি খুঁজছিলাম ছিল। JSON.decycle(a, true)ডেস্কেল ফাংশনের প্যারামিটার হিসাবে সত্য হয়ে গেলে কী হয়।
রুদ্র

@ রুদ্র ট্র্যাঙ্কটি stringifyNodesকাঁটাচামচে বিকল্পটিকে সত্য করে তোলে । এই যেমন ডাম্প হবে divআইডি সহ = স্ট্রিং "কিছু-আইডি": div#some-id। আপনি কিছু সমস্যা এড়াতে পারবেন, তবে আপনি পুরোপুরি বিপরীতমুখী করতে সক্ষম হবেন না।
Nux

এনপিএম প্যাকেজ রয়েছে এনপিএমজেএস / প্যাকেজ / জসন- জ এস , তবে এটি কিছুক্ষণের জন্য আপডেট করা হয়নি
মাইকেল ফ্রেইজিম

23

আমি @ isaacs- থেকে জেসন-স্ট্রিংফাইফ-নিরাপদ পরীক্ষা করার পরামর্শ দেব - এটি এনপিএম-এ ব্যবহৃত হয়।

বিটিডাব্লু- আপনি যদি নোড.জেএস ব্যবহার না করেন তবে উত্স কোডের প্রাসঙ্গিক অংশটি থেকে আপনি 4-27 লাইনগুলি অনুলিপি করে আটকে দিতে পারেন ।

স্থাপন করা:

$ npm install json-stringify-safe --save

ব্যবহার করা:

// Require the thing
var stringify = require('json-stringify-safe');

// Take some nasty circular object
var theBigNasty = {
  a: "foo",
  b: theBigNasty
};

// Then clean it up a little bit
var sanitized = JSON.parse(stringify(theBigNasty));

এই ফলন:

{
  a: 'foo',
  b: '[Circular]'
}

মনে রাখবেন, @ রব ডাব্লু যেমন ভ্যানিলা JSON.stringify ফাংশনটি উল্লেখ করেছেন ঠিক তেমনই, আপনি "রিপ্লেসার" ফাংশনে দ্বিতীয় তর্ক হিসাবে পাস করে স্যানিটাইজেশন আচরণটিও কাস্টমাইজ করতে পারেন stringify()। আপনি যদি এটি কীভাবে করতে চান তার একটি সাধারণ উদাহরণের প্রয়োজন মনে করেন, আমি স্রেফ একটি কাস্টম রিপ্লেসার লিখেছি যা এখানে মানব-পঠনযোগ্য স্ট্রিংগুলিতে ত্রুটিগুলি, রেজেক্সপস এবং ফাংশনগুলিকে জাল করে ।


13

ভবিষ্যতের গুগলরা যখন আপনার সমস্ত বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সগুলির কীগুলি জানেন না তখন এই সমস্যার সমাধানের জন্য অনুসন্ধান করে , আপনি বিজ্ঞপ্তি উল্লেখগুলি বাতিল করতে JSON.stringify ফাংশনটির চারপাশে একটি মোড়ক ব্যবহার করতে পারেন। Https://gist.github.com/4653128 এ একটি উদাহরণ স্ক্রিপ্ট দেখুন

সমাধানটি মূলত একটি অ্যারেতে পূর্ববর্তী মুদ্রিত অবজেক্টের একটি রেফারেন্স রাখার জন্য নিচে ফোটে এবং কোনও মান ফেরত দেওয়ার আগে একটি replacer ফাংশনে পরীক্ষা করে। এটি কেবলমাত্র বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সকেই অস্বীকার করার চেয়ে জটিলতর কারণ এটি কোনও বিষয়কে দু'বার মুদ্রণও নিষিদ্ধ করে, এর মধ্যে একটির দিকটি প্রভাবিত করে যা বৃত্তাকার উল্লেখগুলি এড়ানো হয় avoid

উদাহরণ মোড়ানো:

function stringifyOnce(obj, replacer, indent){
    var printedObjects = [];
    var printedObjectKeys = [];

    function printOnceReplacer(key, value){
        var printedObjIndex = false;
        printedObjects.forEach(function(obj, index){
            if(obj===value){
                printedObjIndex = index;
            }
        });

        if(printedObjIndex && typeof(value)=="object"){
            return "(see " + value.constructor.name.toLowerCase() + " with key " + printedObjectKeys[printedObjIndex] + ")";
        }else{
            var qualifiedKey = key || "(empty key)";
            printedObjects.push(value);
            printedObjectKeys.push(qualifiedKey);
            if(replacer){
                return replacer(key, value);
            }else{
                return value;
            }
        }
    }
    return JSON.stringify(obj, printOnceReplacer, indent);
}

3
চমৎকার কোড। যদিও, আপনি লিখতে আপনাকে অবশ্যই একটি নিরীহ ত্রুটি আছে if(printedObjIndex)যখন আপনি লেখা উচিত if(printedObjIndex==false)কারণ indexএও হতে পারে 0যা অনুবাদ করা হয় false, যদি না আপনি স্পষ্টভাবে অন্যথায় রাষ্ট্র।
লোক মোগ্রাবি

1
@ গুগমোগ্রাবি মানে না ===? 0 == falseহয় true, 0 === falseহয় false। ; But) তবে আমি বরং printedObjIndexমিথ্যা হিসাবে আরম্ভ করব না , তারপরে আপনি এটি পরীক্ষা করতে পারেন undefinedযাতে আপনি (ভাল, ত্রিঞ্জাজের) রূপকগুলিকে অদ্ভুতভাবে মিশ্রিত করছেন না।
ruffin

পছন্দ করেছেন হ্যাঁ স্পষ্টতই, এই জাতীয় নির্বিকারের ভুলগুলি ধরার জন্য সর্বদা কঠোর সাম্য এবং জশিন্ট ব্যবহার করুন।
লোক মোগ্রাবি

4

একটি replacer সঙ্গে JSON.stringify পদ্ধতি ব্যবহার করুন। আরও তথ্যের জন্য এই ডকুমেন্টেশন পড়ুন। http://msdn.microsoft.com/en-us/library/cc836459%28v=vs.94%29.aspx

var obj = {
  a: "foo",
  b: obj
}

var replacement = {"b":undefined};

alert(JSON.stringify(obj,replacement));

চক্রীয় রেফারেন্স সহ প্রতিস্থাপন অ্যারেটি তৈরি করার একটি উপায় বের করুন। কোনও প্রকার সম্পত্তি 'অবজেক্ট' (রেফারেন্স) টাইপের কিনা এবং বিজ্ঞপ্তি রেফারেন্স যাচাই করার জন্য সঠিক সমতা চেক (===) রয়েছে কিনা তা জানতে আপনি টাইপফ পদ্ধতিটি ব্যবহার করতে পারেন।


4
এটি কেবল আইইতে কাজ করতে পারে (এমএসডিএন মাইক্রোসফ্টের নথিভুক্ত, এবং মাইক্রোসফ্ট আইই তৈরি করে) এই বিষয়টি বিবেচনা করে। ফায়ারফক্স / ক্রোমে, jsfiddle.net/ppmaW বৃত্তাকার রেফারেন্স ত্রুটি উত্পন্ন করে। এফওয়াইআই: var obj = {foo:obj}কোন বিজ্ঞপ্তি রেফারেন্স তৈরি করে না । পরিবর্তে, এটি এমন একটি বস্তু তৈরি করে যার fooবৈশিষ্ট্যটি পূর্বের মানকে বোঝায় obj( undefinedযদি পূর্বে সংজ্ঞায়িত না হয় তবে এর কারণে ঘোষিত হয় var obj)।
রব ডাব্লু

4

যদি

console.log(JSON.stringify(object));

ফলাফল এ

প্রকারের ত্রুটি: চক্রীয় বস্তুর মান

তারপরে আপনি এটি মুদ্রণ করতে চাইবেন:

var output = '';
for (property in object) {
  output += property + ': ' + object[property]+'; ';
}
console.log(output);

21
কারণ এটি কেবল একটি স্তর ছাপায়?
অ্যালেক্স টারপিন

আমি খুব সরল সরল পদক্ষেপটি এটিকে উত্সাহিত করেছি কারণ এটি ক্রোমের বাক্সের বাইরে আমার জন্য কাজ করেছিল। চমৎকার
ভালবাসা এবং শান্তি - জো Codeswell

4
var a={b:"b"};
a.a=a;
JSON.stringify(preventCircularJson(a));

মূল্যায়ন:

"{"b":"b","a":"CIRCULAR_REFERENCE_REMOVED"}"

ফাংশন সহ:

/**
 * Traverses a javascript object, and deletes all circular values
 * @param source object to remove circular references from
 * @param censoredMessage optional: what to put instead of censored values
 * @param censorTheseItems should be kept null, used in recursion
 * @returns {undefined}
 */
function preventCircularJson(source, censoredMessage, censorTheseItems) {
    //init recursive value if this is the first call
    censorTheseItems = censorTheseItems || [source];
    //default if none is specified
    censoredMessage = censoredMessage || "CIRCULAR_REFERENCE_REMOVED";
    //values that have allready apeared will be placed here:
    var recursiveItems = {};
    //initaite a censored clone to return back
    var ret = {};
    //traverse the object:
    for (var key in source) {
        var value = source[key]
        if (typeof value == "object") {
            //re-examine all complex children again later:
            recursiveItems[key] = value;
        } else {
            //simple values copied as is
            ret[key] = value;
        }
    }
    //create list of values to censor:
    var censorChildItems = [];
    for (var key in recursiveItems) {
        var value = source[key];
        //all complex child objects should not apear again in children:
        censorChildItems.push(value);
    }
    //censor all circular values
    for (var key in recursiveItems) {
        var value = source[key];
        var censored = false;
        censorTheseItems.forEach(function (item) {
            if (item === value) {
                censored = true;
            }
        });
        if (censored) {
            //change circular values to this
            value = censoredMessage;
        } else {
            //recursion:
            value = preventCircularJson(value, censoredMessage, censorChildItems.concat(censorTheseItems));
        }
        ret[key] = value

    }

    return ret;
}

3

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমি একটি এনপিএম প্যাকেজটি সুপারিশ করতে চাই যা আমি তৈরি করেছি স্মার্ট-সার্কুলার , যা প্রস্তাবিত অন্যান্য পদ্ধতি থেকে আলাদাভাবে কাজ করে। আপনি যদি বড় এবং গভীর অবজেক্ট ব্যবহার করেন তবে এটি বিশেষভাবে কার্যকর ।

কিছু বৈশিষ্ট্যগুলি হ'ল:

  • বিজ্ঞপ্তিযুক্ত রেফারেন্সগুলি বা বস্তুর অভ্যন্তরে কেবল পুনরাবৃত্ত স্ট্রাকচারগুলির পরিবর্তে তার প্রথম সংঘটন (কেবল স্ট্রিং নয় [বৃত্তাকার] );

  • প্রস্থ-প্রথম অনুসন্ধানে বিজ্ঞপ্তিগুলি সন্ধান করে, প্যাকেজটি নিশ্চিত করে যে এই পথটি যতটা সম্ভব ছোট, যা খুব বড় এবং গভীর অবজেক্টগুলির সাথে ডিল করার সময় গুরুত্বপূর্ণ, যেখানে পাথগুলি বিরক্তিকরভাবে দীর্ঘ এবং অনুসরণ করা শক্ত হতে পারে (কাস্টম প্রতিস্থাপনের ক্ষেত্রে JSON.stringify একটি ডিএফএস করে);

  • ব্যক্তিগতকৃত প্রতিস্থাপনগুলি, অবজেক্টের কম গুরুত্বপূর্ণ অংশগুলিকে সরলকরণ বা উপেক্ষা করার জন্য সহজ;

  • শেষ অবধি, ক্ষেত্রগুলি রেফারেন্স করা ক্ষেত্রটি অ্যাক্সেস করার জন্য প্রয়োজনীয় পথগুলি সঠিকভাবে রচনা করা হয়েছিল, যা আপনাকে ডিবাগ করতে সহায়তা করতে পারে।


3

JSON.stringify () এর কাছেও দ্বিতীয় যুক্তি আপনি মূল নাম যে প্রতি বস্তুর এটা আপনার ডেটা মধ্যে encounters থেকে সংরক্ষিত করা উচিত একটি অ্যারের নির্দিষ্ট করার অনুমতি দেয়। এটি সমস্ত ব্যবহারের ক্ষেত্রে কার্যকর না হতে পারে তবে এটি একটি সহজ সমাধান।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

var obj = {
    a: "foo",
    b: this
}

var json = JSON.stringify(obj, ['a']);
console.log(json);
// {"a":"foo"}

দ্রষ্টব্য: আশ্চর্যজনকভাবে, ওপি থেকে অবজেক্টের সংজ্ঞা সর্বশেষতম ক্রোম বা ফায়ারফক্সে একটি বিজ্ঞপ্তি রেফারেন্স ত্রুটি ফেলে না। এই উত্তরে সংজ্ঞা পরিবর্তন করা হয়েছে যাতে এটি করেনি একটি ত্রুটি নিক্ষেপ করা।



এই একটির উত্তর গ্রহণ করা উচিত
ম্যানিক ডিপ্রেশন

2

জেএসএন যেভাবে কাজ করে (সম্ভবত প্রস্তাবিত নয়, তবে অতি সাধারণ) এর ওভাররাইডিংয়ের উত্তর আপডেট করতে, ব্যবহার করবেন না circular-json(এটি অবমূল্যায়িত)। পরিবর্তে, উত্তরাধিকারী ব্যবহার করুন, সমতল:

https://www.npmjs.com/package/flatted

উপরের পুরানো উত্তরটি @ ব্যবহারকারী 1541685 থেকে নেওয়া হয়েছে, তবে নতুনটির সাথে প্রতিস্থাপন করেছেন:

npm i --save flatted

তারপরে আপনার জেএস ফাইলে

const CircularJSON = require('flatted');
const json = CircularJSON.stringify(obj);

1

আমি গিথুবে বিজ্ঞপ্তি-জসন লাইব্রেরি পেয়েছি এবং এটি আমার সমস্যার পক্ষে ভাল কাজ করেছে।

কিছু ভাল বৈশিষ্ট্য যা আমি দরকারী পেয়েছি:

  • মাল্টি প্ল্যাটফর্মের ব্যবহার সমর্থন করে তবে আমি এ পর্যন্ত কেবল নোড.জেএস দিয়ে এটি পরীক্ষা করেছি।
  • এপিআই একই তাই আপনাকে যাএসএন প্রতিস্থাপন হিসাবে তা অন্তর্ভুক্ত করে ব্যবহার করতে হবে।
  • এটির নিজস্ব পার্সিং পদ্ধতি রয়েছে যাতে আপনি 'বিজ্ঞপ্তি' সিরিয়ালযুক্ত ডেটাটিকে আবার বস্তুতে রূপান্তর করতে পারেন।

2
এই লাইব্রেরিটি আমার জন্য একটি ত্রুটি ছুঁড়েছে তাই আমাকে আরও একটি সন্ধান করতে হবে। ত্রুটি TypeError: toISOString বস্তুর সময়ে String.toJSON (<বেনামী>) এ ফাংশন নয় <বেনামী>। ( স্থানীয় হোস্ট: 8100 / বিল্ড / polyfills.js: 1: 3458 ) JSON.stringify (<বেনামী>) এ বস্তুর সময়ে। স্ট্রিংফাইরেকারশন [স্ট্রিংফাইড হিসাবে] ( লোকালহোস্ট: 8100 / বিল্ড / মেইন.জেএস: 258450: 15 )
মার্ক

1
@ মার্কএলুল আমি 2015 সালে মন্তব্যটি লিখেছি এবং আমি যদি আরও ভাল বিকল্প দেখতে পাই তবে আমি এটি সম্পাদনা করে এখানে পোস্ট করব। আমি এখনও একই কাজটি মাঝেমধ্যে প্রতিদিনের কাজটিতে শেষ করি এবং আমি সাধারণত আমার নিজের ম্যানুয়াল ফাংশনগুলিকে যথাযথ / নিরাপদ পরিদর্শন করে পুনরাবৃত্ত পদ্ধতিতে পছন্দ করি। আমি অপরিচিত হলে সাধারণত কার্যকরী প্রোগ্রামিং চর্চাগুলি পরীক্ষা করে দেখার পরামর্শ দেব, সাধারণত, এটি কম কৌশলযুক্ত এবং আরও নির্ভরযোগ্য হিসাবে এই ধরণের পুনরাবৃত্ত অপারেশনগুলিকে সহজ করে তুলছে।
জ্যাকোপেন

এছাড়াও "টোআইএসএসট্রিং কোনও ফাংশন নয়" কোনও ইভেন্টকে আরও শক্তিশালী করে এবং এটি একটি সাইপ্রাস পরীক্ষায় পুনরায় প্রেরণের চেষ্টা করে
ডেভিন জি রোড

1

আমি এই সমস্যার মতো সমাধান করি:

var util = require('util');

// Our circular object
var obj = {foo: {bar: null}, a:{a:{a:{a:{a:{a:{a:{hi: 'Yo!'}}}}}}}};
obj.foo.bar = obj;

// Generate almost valid JS object definition code (typeof string)
var str = util.inspect(b, {depth: null});

// Fix code to the valid state (in this example it is not required, but my object was huge and complex, and I needed this for my case)
str = str
    .replace(/<Buffer[ \w\.]+>/ig, '"buffer"')
    .replace(/\[Function]/ig, 'function(){}')
    .replace(/\[Circular]/ig, '"Circular"')
    .replace(/\{ \[Function: ([\w]+)]/ig, '{ $1: function $1 () {},')
    .replace(/\[Function: ([\w]+)]/ig, 'function $1(){}')
    .replace(/(\w+): ([\w :]+GMT\+[\w \(\)]+),/ig, '$1: new Date("$2"),')
    .replace(/(\S+): ,/ig, '$1: null,');

// Create function to eval stringifyed code
var foo = new Function('return ' + str + ';');

// And have fun
console.log(JSON.stringify(foo(), null, 4));

এটি বেশিরভাগ ক্ষেত্রে আমার পক্ষে কাজ করেছে তবে মনে হচ্ছে ক্লাসগুলি যেমন প্রতিনিধিত্ব করছিল _class: ClassName { data: "here" }তাই আমি নিম্নলিখিত নিয়মটি যুক্ত করেছি .replace(/(\w+) {/g, '{ __ClassName__: "$1", ')। আমার ক্ষেত্রে আমি এইচটিসি অনুরোধের অবজেক্টটি কেমন দেখাচ্ছে তা দেখার চেষ্টা করছিলাম।
redbmk

1

আমি জানি এই প্রশ্নটি পুরানো এবং প্রচুর দুর্দান্ত উত্তর রয়েছে তবে আমি এই উত্তরটি নতুন স্বাদের কারণে পোস্ট করছি (এস 5+)


1

যদিও এর যথেষ্ট উত্তর দেওয়া হয়েছে, আপনি অপারেটরটি ব্যবহার করে স্ট্রিংকরণের আগে প্রশ্নে থাকা সম্পত্তিটিও স্পষ্টভাবে মুছে ফেলতে পারেন delete

delete obj.b; 
const jsonObject = JSON.stringify(obj);

অপারেটর মুছুন

এটি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সগুলি সরানোর জন্য জটিল যুক্তি নির্মাণ বা বজায় রাখার প্রয়োজনীয়তা সরিয়ে ফেলবে।


1
function myStringify(obj, maxDeepLevel = 2) {
  if (obj === null) {
    return 'null';
  }
  if (obj === undefined) {
    return 'undefined';
  }
  if (maxDeepLevel < 0 || typeof obj !== 'object') {
    return obj.toString();
  }
  return Object
    .entries(obj)
    .map(x => x[0] + ': ' + myStringify(x[1], maxDeepLevel - 1))
    .join('\r\n');
}

0

এই ধরণের অবজেক্টের সাথে এই সমস্যার সমাধানের জন্য অন্য একটি সমাধান হ'ল এই লাইব্রেরিটি ব্যবহার করা

https://github.com/ericmuyser/stringy

এটি সহজ এবং আপনি কয়েকটি সহজ পদক্ষেপে এটি সমাধান করতে পারেন।


0

অন্যান্য উত্তরের উপর ভিত্তি করে আমি নিম্নলিখিত কোডটি দিয়ে শেষ করি। এটি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্স, কাস্টম কনস্ট্রাক্টরগুলির সাথে অবজেক্টগুলির সাথে বেশ ভাল কাজ করে।

সিরিয়ালায়িত করার জন্য প্রদত্ত বস্তু থেকে,

  • অবজেক্টটি ট্র্যাভার করার সময় আপনি যে সমস্ত বস্তুটি দেখতে পেয়েছেন তা ক্যাশে করুন এবং তাদের প্রত্যেককে একটি স্বতন্ত্র হ্যাশআইডি বরাদ্দ করুন (একটি স্বয়ংক্রিয়-বৃদ্ধিকারী সংখ্যাও কাজ করে)
  • একবার একটি বিজ্ঞপ্তি রেফারেন্স পাওয়া গেলে সেই নতুন ক্ষেত্রটিকে সেই ক্ষেত্রটি বিজ্ঞপ্তি হিসাবে চিহ্নিত করুন এবং মূল বস্তুর হ্যাশআইডিটিকে একটি বৈশিষ্ট্য হিসাবে সংরক্ষণ করুন।

গিথুব লিংক - ডাইসকলডজেএসএন ON

DJSHelper = {};
DJSHelper.Cache = [];
DJSHelper.currentHashID = 0;
DJSHelper.ReviveCache = [];

// DOES NOT SERIALIZE FUNCTION
function DJSNode(name, object, isRoot){
    this.name = name;
    // [ATTRIBUTES] contains the primitive fields of the Node
    this.attributes = {};

    // [CHILDREN] contains the Object/Typed fields of the Node
    // All [CHILDREN] must be of type [DJSNode]
    this.children = []; //Array of DJSNodes only

    // If [IS-ROOT] is true reset the Cache and currentHashId
    // before encoding
    isRoot = typeof isRoot === 'undefined'? true:isRoot;
    this.isRoot = isRoot;
    if(isRoot){
        DJSHelper.Cache = [];
        DJSHelper.currentHashID = 0;

        // CACHE THE ROOT
        object.hashID = DJSHelper.currentHashID++;
        DJSHelper.Cache.push(object);
    }

    for(var a in object){
        if(object.hasOwnProperty(a)){
            var val = object[a];

            if (typeof val === 'object') {
                // IF OBJECT OR NULL REF.

                /***************************************************************************/
                // DO NOT REMOVE THE [FALSE] AS THAT WOULD RESET THE [DJSHELPER.CACHE]
                // AND THE RESULT WOULD BE STACK OVERFLOW
                /***************************************************************************/
                if(val !== null) {
                    if (DJSHelper.Cache.indexOf(val) === -1) {
                        // VAL NOT IN CACHE
                        // ADD THE VAL TO CACHE FIRST -> BEFORE DOING RECURSION
                        val.hashID = DJSHelper.currentHashID++;
                        //console.log("Assigned", val.hashID, "to", a);
                        DJSHelper.Cache.push(val);

                        if (!(val instanceof Array)) {
                            // VAL NOT AN [ARRAY]
                            try {
                                this.children.push(new DJSNode(a, val, false));
                            } catch (err) {
                                console.log(err.message, a);
                                throw err;
                            }
                        } else {
                            // VAL IS AN [ARRAY]
                            var node = new DJSNode(a, {
                                array: true,
                                hashID: val.hashID // HashID of array
                            }, false);
                            val.forEach(function (elem, index) {
                                node.children.push(new DJSNode("elem", {val: elem}, false));
                            });
                            this.children.push(node);
                        }
                    } else {
                        // VAL IN CACHE
                        // ADD A CYCLIC NODE WITH HASH-ID
                        this.children.push(new DJSNode(a, {
                            cyclic: true,
                            hashID: val.hashID
                        }, false));
                    }
                }else{
                    // PUT NULL AS AN ATTRIBUTE
                    this.attributes[a] = 'null';
                }
            } else if (typeof val !== 'function') {
                // MUST BE A PRIMITIVE
                // ADD IT AS AN ATTRIBUTE
                this.attributes[a] = val;
            }
        }
    }

    if(isRoot){
        DJSHelper.Cache = null;
    }
    this.constructorName = object.constructor.name;
}
DJSNode.Revive = function (xmlNode, isRoot) {
    // Default value of [isRoot] is True
    isRoot = typeof isRoot === 'undefined'?true: isRoot;
    var root;
    if(isRoot){
        DJSHelper.ReviveCache = []; //Garbage Collect
    }
    if(window[xmlNode.constructorName].toString().indexOf('[native code]') > -1 ) {
        // yep, native in the browser
        if(xmlNode.constructorName == 'Object'){
            root = {};
        }else{
            return null;
        }
    }else {
        eval('root = new ' + xmlNode.constructorName + "()");
    }

    //CACHE ROOT INTO REVIVE-CACHE
    DJSHelper.ReviveCache[xmlNode.attributes.hashID] = root;

    for(var k in xmlNode.attributes){
        // PRIMITIVE OR NULL REF FIELDS
        if(xmlNode.attributes.hasOwnProperty(k)) {
            var a = xmlNode.attributes[k];
            if(a == 'null'){
                root[k] = null;
            }else {
                root[k] = a;
            }
        }
    }

    xmlNode.children.forEach(function (value) {
        // Each children is an [DJSNode]
        // [Array]s are stored as [DJSNode] with an positive Array attribute
        // So is value

        if(value.attributes.array){
            // ITS AN [ARRAY]
            root[value.name] = [];
            value.children.forEach(function (elem) {
                root[value.name].push(elem.attributes.val);
            });
            //console.log("Caching", value.attributes.hashID);
            DJSHelper.ReviveCache[value.attributes.hashID] = root[value.name];
        }else if(!value.attributes.cyclic){
            // ITS AN [OBJECT]
            root[value.name] = DJSNode.Revive(value, false);
            //console.log("Caching", value.attributes.hashID);
            DJSHelper.ReviveCache[value.attributes.hashID] = root[value.name];
        }
    });

    // [SEPARATE ITERATION] TO MAKE SURE ALL POSSIBLE
    // [CYCLIC] REFERENCES ARE CACHED PROPERLY
    xmlNode.children.forEach(function (value) {
        // Each children is an [DJSNode]
        // [Array]s are stored as [DJSNode] with an positive Array attribute
        // So is value

        if(value.attributes.cyclic){
            // ITS AND [CYCLIC] REFERENCE
            root[value.name] = DJSHelper.ReviveCache[value.attributes.hashID];
        }
    });

    if(isRoot){
        DJSHelper.ReviveCache = null; //Garbage Collect
    }
    return root;
};

DecycledJSON = {};
DecycledJSON.stringify = function (obj) {
    return JSON.stringify(new DJSNode("root", obj));
};
DecycledJSON.parse = function (json, replacerObject) {
    // use the replacerObject to get the null values
    return DJSNode.Revive(JSON.parse(json));
};
DJS = DecycledJSON;

ব্যবহারের উদাহরণ 1:

var obj = {
    id:201,
    box: {
        owner: null,
        key: 'storm'
    },
    lines:[
        'item1',
        23
    ]
};

console.log(obj); // ORIGINAL

// SERIALIZE AND THEN PARSE
var jsonObj = DJS.stringify(obj);
console.log(DJS.parse(jsonObj));

ব্যবহার 2 উদাহরণ:

// PERSON OBJECT

function Person() {
    this.name = null;
    this.child = null;
    this.dad = null;
    this.mom = null;
}
var Dad = new Person();
Dad.name = 'John';
var Mom = new Person();
Mom.name = 'Sarah';
var Child = new Person();
Child.name = 'Kiddo';

Dad.child = Mom.child = Child;
Child.dad = Dad;
Child.mom = Mom;

console.log(Child); // ORIGINAL

// SERIALIZE AND THEN PARSE
var jsonChild = DJS.stringify(Child);
console.log(DJS.parse(jsonChild));

0

এটা চেষ্টা কর:

var obj = {
    a: "foo",
    b: obj
};

var circular_replacer = (value) => {
    var seen = [];
    if (value != null && typeof value == "object") {
        if (seen.indexOf(value) >= 0) return;
        seen.push(value);
    }
    return value;
};

obj = circular_replacer(obj);

seen.push(value)= -D এর পরে কোডের মতো আরও কয়েকটি লাইন থাকা উচিত নয় ? পছন্দfor (var key in value) {value[key] = circular_replacer(value[key]);}
ক্লেসুন

কোড-কেবল উত্তরগুলি নিরুৎসাহিত করা হয়। দয়া করে সম্পাদনাতে ক্লিক করুন এবং আপনার কোডটি প্রশ্নটিকে কীভাবে সম্বোধন করে তা সংক্ষেপ করে কিছু শব্দ যুক্ত করুন বা সম্ভবত আপনার উত্তরটি পূর্ববর্তী উত্তর / উত্তরগুলির থেকে আলাদা কীভাবে ব্যাখ্যা করুন। পর্যালোচনা থেকে
নিক

0

আমার সমাধানে, যদি আপনি কোনও চক্রের দিকে যান তবে এটি কেবল "চক্র" (বা কিছুই নয়) বলে না, এটি ফু এর মতো কিছু বলে: উপরের অবজেক্ট # 42 দেখুন, এবং আপনাকে ফু পয়েন্টগুলি কোথায় স্ক্রোল করে অনুসন্ধান করতে পারে তা দেখতে # 42 অবজেক্টের জন্য (প্রতিটি বস্তু যখন এটি শুরু হয় তখন কিছু পূর্ণসংখ্যার xxx সহ বস্তু # xxx বলে)

স্নিপেট:

(function(){
	"use strict";
	var ignore = [Boolean, Date, Number, RegExp, String];
	function primitive(item){
		if (typeof item === 'object'){
			if (item === null) { return true; }
			for (var i=0; i<ignore.length; i++){
				if (item instanceof ignore[i]) { return true; }
			}
			return false;
		} else {
			return true;
		}
	}
	function infant(value){
		return Array.isArray(value) ? [] : {};
	}
	JSON.decycleIntoForest = function decycleIntoForest(object, replacer) {
		if (typeof replacer !== 'function'){
			replacer = function(x){ return x; }
		}
		object = replacer(object);
		if (primitive(object)) return object;
		var objects = [object];
		var forest  = [infant(object)];
		var bucket  = new WeakMap(); // bucket = inverse of objects 
		bucket.set(object, 0);       // i.e., map object to index in array
		function addToBucket(obj){
			var result = objects.length;
			objects.push(obj);
			bucket.set(obj, result);
			return result;
		}
		function isInBucket(obj){
			return bucket.has(obj);
			// objects[bucket.get(obj)] === obj, iff true is returned
		}
		function processNode(source, target){
			Object.keys(source).forEach(function(key){
				var value = replacer(source[key]);
				if (primitive(value)){
					target[key] = {value: value};
				} else {
					var ptr;
					if (isInBucket(value)){
						ptr = bucket.get(value);
					} else {
						ptr = addToBucket(value);
						var newTree = infant(value);
						forest.push(newTree);
						processNode(value, newTree);
					}
					target[key] = {pointer: ptr};
				}
			});
		}
		processNode(object, forest[0]);
		return forest;
	};
})();
the = document.getElementById('the');
function consoleLog(toBeLogged){
  the.textContent = the.textContent + '\n' + toBeLogged;
}
function show(root){
	var cycleFree = JSON.decycleIntoForest(root);
	var shown = cycleFree.map(function(tree, idx){ return false; });
	var indentIncrement = 4;
	function showItem(nodeSlot, indent, label){
	  leadingSpaces = ' '.repeat(indent);
      leadingSpacesPlus = ' '.repeat(indent + indentIncrement);
	  if (shown[nodeSlot]){
	  consoleLog(leadingSpaces + label + ' ... see above (object #' + nodeSlot + ')');
        } else {
		  consoleLog(leadingSpaces + label + ' object#' + nodeSlot);
		  var tree = cycleFree[nodeSlot];
		  shown[nodeSlot] = true;
		  Object.keys(tree).forEach(function(key){
			var entry = tree[key];
			if ('value' in entry){
			  consoleLog(leadingSpacesPlus + key + ": " + entry.value);
                } else {
					if ('pointer' in entry){
						showItem(entry.pointer, indent+indentIncrement, key);
                    }
                }
			});
        }
    }
	showItem(0, 0, 'root');
}
cities4d = {
	Europe:{
		north:[
			{name:"Stockholm", population:1000000, temp:6},
			{name:"Helsinki", population:650000, temp:7.6}
		],
		south:[
			{name:"Madrid", population:3200000, temp:15},
			{name:"Rome", population:4300000, temp:15}
		]
	},
	America:{
		north:[
			{name:"San Francisco", population:900000, temp:14},
			{name:"Quebec", population:530000, temp:4}
		],
		south:[
			{name:"Rio de Janeiro", population:7500000, temp:24},
			{name:"Santiago", population:6300000, temp:14}
		]
	},
	Asia:{
		north:[
			{name:"Moscow", population:13200000, temp:6}
		]
	}
};
cities4d.Europe.north[0].alsoStartsWithS = cities4d.America.north[0];
cities4d.Europe.north[0].smaller = cities4d.Europe.north[1];
cities4d.Europe.south[1].sameLanguage = cities4d.America.south[1];
cities4d.Asia.ptrToRoot = cities4d;
show(cities4d)
<pre id="the"></pre>

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.