जावास्क्रिप्ट डेटा स्वरूपण / सुंदर प्रिंटर


124

मैं pretty printडीबगिंग के लिए मानव-पठनीय रूप में जावास्क्रिप्ट डेटा संरचना का एक रास्ता खोजने की कोशिश कर रहा हूं ।

मेरे पास एक बड़ी और जटिल डेटा संरचना है जिसे जेएस में संग्रहीत किया जा रहा है और मुझे इसमें हेरफेर करने के लिए कुछ कोड लिखने की आवश्यकता है। यह पता लगाने के लिए कि मैं क्या कर रहा हूं और मैं कहां गलत हो रहा हूं, मुझे वास्तव में डेटा संरचना को पूरी तरह से देखने में सक्षम होना चाहिए, और जब भी मैं यूआई के माध्यम से बदलाव करता हूं, तो इसे अपडेट कर सकता हूं।

यह सब सामान मैं खुद को संभाल सकता हूं, इसके अलावा एक जावास्क्रिप्ट डेटा संरचना को मानव-पठनीय स्ट्रिंग में डंप करने का एक अच्छा तरीका खोजने के अलावा। JSON करना होगा, लेकिन यह वास्तव में अच्छी तरह से स्वरूपित और इंडेंट किया जाना चाहिए। मैं आमतौर पर इसके लिए फायरबग के उत्कृष्ट डोम डंपिंग सामान का उपयोग करता हूं, लेकिन मुझे वास्तव में एक बार में पूरी संरचना को देखने में सक्षम होना चाहिए, जो फायरबग में संभव नहीं लगता है।

किसी भी सुझाव का स्वागत है।

अग्रिम में धन्यवाद।


निश्चित नहीं है कि आपको उत्तरों के संपादन के बारे में सूचित किया गया है। इसलिए मैं आपको यह बताने के लिए यह टिप्पणी लिखता हूं कि मैंने इंडेंट डंप का अपना संस्करण जोड़ा। :-)
फीलो

नोट: JSON.stringify () उत्तर काफी उपयोगी प्रतीत होता है, हालाँकि इसे 'उत्तर' के रूप में स्वीकार नहीं किया गया है।
गुरु

आप nodedump का उपयोग करके वस्तुओं का दृश्य और सहज उत्पादन प्राप्त कर सकते हैं: github.com/ragamufin/nodedump
ragamufin

वहाँ एक नज़र रखना: stackoverflow.com/questions/4810841/…
बंदर

जवाबों:


31

मैंने जेएस ऑब्जेक्ट को पठनीय रूप में डंप करने के लिए एक फ़ंक्शन लिखा था, हालांकि आउटपुट इंडेंट नहीं है, लेकिन इसे जोड़ने के लिए बहुत मुश्किल नहीं होना चाहिए: मैंने यह फ़ंक्शन एक से बनाया जिसे मैंने लुआ के लिए बनाया था (जो कि बहुत अधिक जटिल है ) जिसने इस इंडेंटेशन मुद्दे को संभाला।

यहाँ "सरल" संस्करण है:

function DumpObject(obj)
{
  var od = new Object;
  var result = "";
  var len = 0;

  for (var property in obj)
  {
    var value = obj[property];
    if (typeof value == 'string')
      value = "'" + value + "'";
    else if (typeof value == 'object')
    {
      if (value instanceof Array)
      {
        value = "[ " + value + " ]";
      }
      else
      {
        var ood = DumpObject(value);
        value = "{ " + ood.dump + " }";
      }
    }
    result += "'" + property + "' : " + value + ", ";
    len++;
  }
  od.dump = result.replace(/, $/, "");
  od.len = len;

  return od;
}

मैं इसे थोड़ा सुधार कर देखूंगा।
नोट 1: इसका उपयोग करने के लिए, od = DumpObject(something)od.dump का उपयोग करें और उसका उपयोग करें। क्योंकि मैं एक और उद्देश्य के लिए लेन मूल्य भी चाहता था (मदों की संख्या)। यह केवल स्ट्रिंग को वापस करने के लिए तुच्छ है।
नोट 2: यह संदर्भ में लूप को हैंडल नहीं करता है।

संपादित करें

मैंने इंडेंटेड वर्जन बनाया।

function DumpObjectIndented(obj, indent)
{
  var result = "";
  if (indent == null) indent = "";

  for (var property in obj)
  {
    var value = obj[property];
    if (typeof value == 'string')
      value = "'" + value + "'";
    else if (typeof value == 'object')
    {
      if (value instanceof Array)
      {
        // Just let JS convert the Array to a string!
        value = "[ " + value + " ]";
      }
      else
      {
        // Recursive dump
        // (replace "  " by "\t" or something else if you prefer)
        var od = DumpObjectIndented(value, indent + "  ");
        // If you like { on the same line as the key
        //value = "{\n" + od + "\n" + indent + "}";
        // If you prefer { and } to be aligned
        value = "\n" + indent + "{\n" + od + "\n" + indent + "}";
      }
    }
    result += indent + "'" + property + "' : " + value + ",\n";
  }
  return result.replace(/,\n$/, "");
}

पुनरावर्ती कॉल के साथ लाइन पर अपना इंडेंटेशन चुनें, और आप इस एक के बाद टिप्पणी लाइन को स्विच करके स्टाइल को ब्रेस करें।

... मैं देख रहा हूं कि आपने अपना संस्करण तैयार किया है, जो अच्छा है। आगंतुकों के पास एक विकल्प होगा।


1
मुझे पसंद है;) इसे ठीक से काम करने के लिए नहीं मिल सकता है, लेकिन अगर आप बुरा नहीं मानते हैं, तो मैं बेशर्मी से अवधारणा को चोरी करने जा रहा हूं और अपना खुद का नाम लिखूंगा :)
Dan

2
इस दृष्टिकोण के एक छोटे से आने (JSON.stringify विधि जेसन के साथ तुलना में) का कहना है कि यह वस्तुओं के सरणियों को ठीक से नहीं दिखाता है। जब आपके पास ऑब्जेक्ट्स की एक सरणी होती है, तो यह [ऑब्जेक्ट ऑब्जेक्ट] के रूप में दिखाई देता है।
रेयान

@ रियान: आप ब्राउज़र की मूल वस्तुओं का मतलब है? हां, अपने कोड को वापस देखते हुए, मैंने देखा कि मैंने एक टिप्पणी जोड़ी है: // बहुत बुरा अगर एक क्षेत्र एक वस्तु है ...: -पी यहां मेरे परीक्षण के लिए ठीक है ... उपयोगकर्ता द्वारा बनाई गई संरचनाओं को डंप करना ठीक है। मुझे लगता है कि नीचे विकल्प हैं, अगर आपको कुछ और अधिक मजबूत चाहिए।
फीलो

मैं इसका उपयोग नहीं कर सकता। मैं अनंत लूप प्राप्त करता हूं जब मैं कुछ जोंस डेटा को डंप करने की कोशिश करता हूं।
नीनी

1
@RaphaelDDL & PhiLho - अधिकतम कॉल स्टैक आकार को एक छोटी वस्तु पर भी ट्रिगर किया जा सकता है; खुद के लिए एक संपत्ति संदर्भ के साथ। इस तरह के संदर्भ से इस फ़ंक्शन के साथ एक अनंत लूप होगा।
स्काइबुलक

233

इस तरह से क्रोकफोर्ड के JSON.stringify का उपयोग करें:

var myArray = ['e', {pluribus: 'unum'}];
var text = JSON.stringify(myArray, null, '\t'); //you can specify a number instead of '\t' and that many spaces will be used for indentation...

चर textइस तरह दिखेगा:

[
  "e",
   {
      "pluribus": "unum"
   }
]

वैसे, इसके लिए जेएस फाइल से ज्यादा कुछ नहीं चाहिए - यह किसी भी लाइब्रेरी आदि के साथ काम करेगा।


5
यह लगभग निश्चित रूप से सबसे अच्छा जवाब है जिसे आप प्राप्त करने जा रहे हैं। मैंने JSON.stringified डेटा संरचनाओं को पढ़ने और संपादित करने के लिए 4 या 5 गैर-प्रोग्रामर को सिखाया है और उन्हें कॉन्फ़िगरेशन फ़ाइलों के लिए बड़े पैमाने पर उपयोग करें।
जोएल अनयर

1
अजीब है कि यह समस्याएं पैदा करेगा - यह "JSON" नाम को वैश्विक नामस्थान से परिचित कराता है, जिससे आपको समस्याएं हो सकती हैं। "JSON" के लिए अपने नाम स्थान की जाँच से पहले अगर एक टक्कर मौजूद है देखने के लिए इस जोड़ने।
जेसन बंटिंग

1
खैर, प्रोटोटाइप बुराई की तरह है ...;)
जेसन बंटिंग

7
इस पर एक अद्यतन, फ़ायरफ़ॉक्स 3.5 और इसके बाद के संस्करण के साथ, JSON.stringify बिल्ट-इन है। ( developer.mozilla.org/En/Using_JSON_in_Firefox ), इसलिए यदि आप केवल डीबगिंग उद्देश्यों के लिए JSON ऑब्जेक्ट देखने का प्रयास कर रहे हैं, तो आप इसे बिना अतिरिक्त JS निर्भरता के साथ कर सकते हैं।
ग्रेग बर्नहार्ट

3
क्रोम में भी। हालाँकि, JSON.stringify परिपत्र डेटा JSON.stringify((function(){var x = []; x.push(x); return x})())और कई अन्य प्रकार की वस्तुओं पर विफल रहता है JSON.stringify(/foo/)
१०:१६ बजे क्रैगन जेवियर सीटकेर


15

में Firebug, तुम बस अगर console.debug ("%o", my_object)आप उस पर कंसोल में क्लिक करें और एक इंटरैक्टिव वस्तु एक्सप्लोरर डाल सकते हैं। यह संपूर्ण ऑब्जेक्ट दिखाता है, और आपको नेस्टेड ऑब्जेक्ट्स का विस्तार करने देता है।


1
इसके साथ समस्या यह है कि यह केवल 'सबसे ऊपरी' ऑब्जेक्ट दिखाता है - मुझे दर्जनों नेस्टेड ऑब्जेक्ट मिले हैं, और मुझे वास्तव में एक बार में पूरी सामग्री देखने में सक्षम होने की आवश्यकता है, और महत्वपूर्ण रूप से, देखें कि चीजें कहां बदल रही हैं। इसलिए फायरबग वास्तव में इस मामले में मेरे लिए काम नहीं कर रहा है।
दान

(हाँ मुझे पता है कि आप उन्हें विस्तारित करने के लिए क्लिक कर सकते हैं, लेकिन हर बार जब मैं डेटा को डंप करना चाहता हूं, तो 10 या तो लिंक पर क्लिक करना - मैं बहुत धीमी प्रगति कर रहा हूं)
दान

1
यह क्रोम में भी काम करता है (और इसलिए शायद सफारी में)।
बजे क्रैगन जेवियर सीटेकर


9

अपनी वस्तु को देखने के लिए एक बढ़िया तरीका खोजने वालों के लिए , prettyPrint.js की जाँच करें

आपके डॉच पर कहीं मुद्रित करने के लिए कॉन्फ़िगर करने योग्य दृश्य विकल्पों के साथ एक तालिका बनाता है। से बेहतर दिखने के लिए console

var tbl = prettyPrint( myObject, { /* options such as maxDepth, etc. */ });
document.body.appendChild(tbl);

यहाँ छवि विवरण दर्ज करें


6

मैं प्रोग्रामिंग कर रहा हूं Rhinoऔर मैं यहां पोस्ट किए गए किसी भी जवाब से संतुष्ट नहीं था। इसलिए मैंने अपना खुद का सुंदर प्रिंटर लिखा है:

function pp(object, depth, embedded) { 
  typeof(depth) == "number" || (depth = 0)
  typeof(embedded) == "boolean" || (embedded = false)
  var newline = false
  var spacer = function(depth) { var spaces = ""; for (var i=0;i<depth;i++) { spaces += "  "}; return spaces }
  var pretty = ""
  if (      typeof(object) == "undefined" ) { pretty += "undefined" }
  else if ( typeof(object) == "boolean" || 
            typeof(object) == "number" ) {    pretty += object.toString() } 
  else if ( typeof(object) == "string" ) {    pretty += "\"" + object + "\"" } 
  else if (        object  == null) {         pretty += "null" } 
  else if ( object instanceof(Array) ) {
    if ( object.length > 0 ) {
      if (embedded) { newline = true }
      var content = ""
      for each (var item in object) { content += pp(item, depth+1) + ",\n" + spacer(depth+1) }
      content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
      pretty += "[ " + content + "\n" + spacer(depth) + "]"
    } else { pretty += "[]" }
  } 
  else if (typeof(object) == "object") {
    if ( Object.keys(object).length > 0 ){
      if (embedded) { newline = true }
      var content = ""
      for (var key in object) { 
        content += spacer(depth + 1) + key.toString() + ": " + pp(object[key], depth+2, true) + ",\n" 
      }
      content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
      pretty += "{ " + content + "\n" + spacer(depth) + "}"
    } else { pretty += "{}"}
  }
  else { pretty += object.toString() }
  return ((newline ? "\n" + spacer(depth) : "") + pretty)
}

आउटपुट इस तरह दिखता है:

js> pp({foo:"bar", baz: 1})
{ foo: "bar",
  baz: 1
}
js> var taco
js> pp({foo:"bar", baz: [1,"taco",{"blarg": "moo", "mine": "craft"}, null, taco, {}], bleep: {a:null, b:taco, c: []}})
{ foo: "bar",
  baz: 
    [ 1,
      "taco",
      { blarg: "moo",
        mine: "craft"
      },
      null,
      undefined,
      {}
    ],
  bleep: 
    { a: null,
      b: undefined,
      c: []
    }
}

मैंने इसे भविष्य में जो भी बदलाव की आवश्यकता हो, उसके लिए एक जिस्ट के रूप में पोस्ट किया है।


7
यह एक सुंदर प्रिंटर हो सकता है लेकिन कोड वास्तव में बहुत सुंदर नहीं दिखता है :)
Xion

3

jsDump

jsDump.parse([
    window,
    document,
    { a : 5, '1' : 'foo' },
    /^[ab]+$/g,
    new RegExp('x(.*?)z','ig'),
    alert, 
    function fn( x, y, z ){
        return x + y; 
    },
    true,
    undefined,
    null,
    new Date(),
    document.body,
    document.getElementById('links')
])

हो जाता है

[
   [Window],
   [Document],
   {
      "1": "foo",
      "a": 5
   },
   /^[ab]+$/g,
   /x(.*?)z/gi,
   function alert( a ){
      [code]
   },
   function fn( a, b, c ){
      [code]
   },
   true,
   undefined,
   null,
   "Fri Feb 19 2010 00:49:45 GMT+0300 (MSK)",
   <body id="body" class="node"></body>,
   <div id="links">
]

क्विंट (jQuery द्वारा उपयोग किया जाने वाला यूनिट-टेस्टिंग फ्रेमवर्क), jsDump के थोड़े पैचेड संस्करण का उपयोग कर रहा है।


JSON.stringify () कुछ मामलों पर सबसे अच्छा विकल्प नहीं है।

JSON.stringify({f:function(){}}) // "{}"
JSON.stringify(document.body)    // TypeError: Converting circular structure to JSON

2

फील्हो की अगुआई करते हुए (बहुत बहुत धन्यवाद :)), मैंने अपना लेखन समाप्त कर दिया क्योंकि मैं अपनी इच्छा के मुताबिक काम नहीं कर पा रहा था। यह बहुत कठिन है और तैयार है, लेकिन यह वह काम करता है जिसकी मुझे ज़रूरत है। उत्कृष्ट सुझावों के लिए आप सभी का धन्यवाद।

यह शानदार कोड नहीं है, मुझे पता है, लेकिन इसके लायक क्या है, यहां यह है। किसी को यह उपयोगी लग सकता है:

// Usage: dump(object)
function dump(object, pad){
    var indent = '\t'
    if (!pad) pad = ''
    var out = ''
    if (object.constructor == Array){
        out += '[\n'
        for (var i=0; i<object.length; i++){
            out += pad + indent + dump(object[i], pad + indent) + '\n'
        }
        out += pad + ']'
    }else if (object.constructor == Object){
        out += '{\n'
        for (var i in object){
            out += pad + indent + i + ': ' + dump(object[i], pad + indent) + '\n'
        }
        out += pad + '}'
    }else{
        out += object
    }
    return out
}

1
वैसे, भले ही आप कर सकते हैं, आपको अर्धविराम के बिना लाइनों को समाप्त नहीं करना चाहिए। इसके अलावा, __ if करने का मानक तरीका (यदि? (पैड) पैड = '__ होगा: __ पैड = (पैड || ’’) __
जेसन बंटिंग

मैं आपकी बात मान लेता हूँ अगर (foo) foo = ... बनाम foo = (foo || ...), लेकिन अर्धविराम के साथ सभी पंक्तियों को समाप्त करने का औचित्य क्या है?
दान

1
यदि आप ऐसा नहीं करते हैं, तो आप आसानी से अपने कोड को कम करने में असमर्थ होंगे (जब तक कि आपके द्वारा उपयोग किया जाने वाला मिनीफ़ायर आपके लिए अर्धविराम चिपकाने के लिए काफी अच्छा न हो) आप भाषा के कुछ खराब आइडिओसिप्रेसिज़ में चलेंगे। अधिक जानकारी के लिए stackoverflow.com/questions/42247 देखें ।
जेसन बंटिंग

1
अगर (पैड) पैड = ''; सस्ता है, पैड की तुलना में अधिक लचीला और अधिक पठनीय है = (पैड || ''); एक मिनट की राशि से। यदि आप उस फॉर्म पर जोर देते हैं, तो बाहर के कोष्ठक को हटा दें। पैड = पैड || ''; अर्धविराम के 3 कारण: JS ऑटो-इंसर्ट एंड-लाइन अर्धविराम जब यह देखता है कि उन्हें छोड़ने से कोई त्रुटि होगी। 1) यह अपने आप को जोड़ने की तुलना में एक नन्हा सा पतला है, और 2) अगली पंक्ति के संयुक्त होने पर त्रुटि न करने के लिए होने पर त्रुटियों को जन्म दे सकता है। 3) आपके कोड को छोटा होने से रोकेगा।
सैमगुडी

1

यह वास्तव में जेसन बंटिंग के "क्रॉकफोर्ड के JSON.stringify का उपयोग करें" पर एक टिप्पणी है, लेकिन मैं उस उत्तर में एक टिप्पणी नहीं जोड़ सका।

जैसा कि टिप्पणियों में कहा गया है, JSON.stringify प्रोटोटाइप (www.prototypjs.org) लाइब्रेरी के साथ अच्छा नहीं खेलता है। हालाँकि, अस्थायी रूप से Array.prototype.toJSON पद्धति जिसे प्रोटोटाइप जोड़ता है, क्रॉकफोर्ड के स्ट्रिफ़ () चलाकर, उन्हें फिर से इस तरह से एक साथ चलाना आसान बनाता है।

  var temp = Array.prototype.toJSON;
  delete Array.prototype.toJSON;
  $('result').value += JSON.stringify(profile_base, null, 2);
  Array.prototype.toJSON = temp;

1

मुझे लगा कि JSON.stringify का उपयोग करने पर जे। बंटिंग की प्रतिक्रिया अच्छी थी। एक तरफ, यदि आप YUI का उपयोग कर रहे हैं तो आप JSON.stringify का उपयोग YUIs JSON ऑब्जेक्ट के माध्यम से कर सकते हैं। मेरे मामले में मुझे HTML को डंप करने की आवश्यकता थी इसलिए PhiLho प्रतिक्रिया को बस ट्विक / कट / पेस्ट करना आसान था।

function dumpObject(obj, indent) 
{
  var CR = "<br />", SPC = "&nbsp;&nbsp;&nbsp;&nbsp;", result = "";
  if (indent == null) indent = "";

  for (var property in obj)
  {
    var value = obj[property];

    if (typeof value == 'string')
    {
      value = "'" + value + "'";
    }
    else if (typeof value == 'object')
    {
      if (value instanceof Array)
      {
        // Just let JS convert the Array to a string!
        value = "[ " + value + " ]";
      }
      else
      {
        var od = dumpObject(value, indent + SPC);
        value = CR + indent + "{" + CR + od + CR + indent + "}";
      }
    }
    result += indent + "'" + property + "' : " + value + "," + CR;
  }
  return result;
}

1

इस धागे में कोड लिखने वाले बहुत से लोग विभिन्न गोचरों के बारे में कई टिप्पणियों के साथ। मुझे यह समाधान पसंद आया क्योंकि यह पूर्ण लग रहा था और बिना किसी निर्भरता के एक एकल फ़ाइल थी।

ब्राउज़र

NodeJS

यह "बॉक्स से बाहर" काम करता है और इसमें नोड और ब्राउज़र दोनों संस्करण हैं (संभवतः बस अलग-अलग आवरण हैं लेकिन मैंने पुष्टि करने के लिए खुदाई नहीं की)।

पुस्तकालय भी सुंदर मुद्रण XML, SQL और CSS का समर्थन करता है, लेकिन मैंने उन सुविधाओं की कोशिश नहीं की है।


0

तत्वों को तार के रूप में प्रिंट करने के लिए एक सरल:

var s = "";
var len = array.length;
var lenMinus1 = len - 1
for (var i = 0; i < len; i++) {
   s += array[i];
   if(i < lenMinus1)  {
      s += ", ";
   }
}
alert(s);

0

मेरे NeatJSON लाइब्रेरी में रूबी और जावास्क्रिप्ट दोनों संस्करण हैं । यह एक (अनुमति) एमआईटी लाइसेंस के तहत स्वतंत्र रूप से उपलब्ध है। आप एक ऑनलाइन डेमो / कन्वर्टर देख सकते हैं:
http://phrogz.net/JS/neatjson/neatjson.html

कुछ विशेषताएं (सभी वैकल्पिक):

  • एक विशिष्ट चौड़ाई में लपेटें; यदि कोई ऑब्जेक्ट या सरणी लाइन पर फिट हो सकती है, तो उसे एक लाइन पर रखा जाता है।
  • किसी ऑब्जेक्ट में सभी कुंजी के लिए कॉलोन संरेखित करें।
  • किसी वस्तु की चाबियों को वर्णानुक्रम में क्रमबद्ध करें।
  • दशमलव की विशिष्ट संख्या के लिए फ़्लोटिंग पॉइंट संख्याओं को प्रारूपित करें।
  • लपेटते समय, एक 'संक्षिप्त' संस्करण का उपयोग करें जो सरणियों और वस्तुओं के लिए खुले / बंद कोष्ठक को पहले / दूसरे मान के समान पंक्ति में रखता है।
  • एरे और ऑब्जेक्ट्स के लिए व्हॉट्सएप को दानेदार तरीके से (कोष्ठक के अंदर, कॉलोन और कॉमा से पहले / बाद में) नियंत्रित करें।
  • वेब ब्राउज़र में और Node.js मॉड्यूल के रूप में काम करता है।

-5

flexjson में एक प्रीप्रिंट () फ़ंक्शन शामिल है जो आपको वह दे सकता है जो आप चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.