Pretty print JSON preserve property order - javascript

I've read several posts on using JSON.stringify to pretty print a JSON string with Javascript. However, it seems to re-order the nodes. I would like to have a formatted JSON object in the same order as the string provided.
Here's an example of what I get using the prescribed methods
var sJson = '{"2":"stuff", "1":"care"}';
alert(JSON.stringify(JSON.parse(sJson), null, 2));
Result:
{
"1": "care",
"2": "stuff"
}
Desired Result:
{
"2": "stuff",
"1": "care"
}
I'm happy to use an external library if JSON.stringify is unable to do this. Note: I'm starting with a minified JSON string from the server.

Because in JavaScript Objects are not ordered, properties in an Object do not preserve order. In order to keep your order you would need to change your JSON to use an array instead: [{"2":"stuff"}, {"1":"care"}].

We had a similar question regarding JSON formatting for a display. A couple of robust solutions are available:
The 'json-order' package offers parsing, formatting & pretty-printing with stable ordering. This is based on having ordered input.
The 'fast-json-stable-stringify' package offers deterministic formatting based on sorting.
My quick testing with Chrome also found that JSON.parse() seemed to preserve order; this covers much of the browser market (Chrome, Edge, etc) but is not guaranteed on other browsers. This may offer a cheap partial solution, but is not fully robust.

I was able to port the php function I found on this page; it's working like a champ.
function pad(width, string, padding) {
return (width <= string.length) ? string : pad(width, padding + string, padding)
}
function json_pretty(json, html)
{
var
out = '',
nl = "\n",
cnt = 0,
tab = 4,
len = json.length,
space = ' ';
if(html == true) {
space = ' ';
nl = '<br/>';
}
k = space.length ? space.length : 1;
for (i=0; i<=len; i++) {
char = json.substring(i, i+1);
if(char == '}' || char == ']') {
cnt--;
out += nl + '' + pad(tab * cnt * k, '', space);
}
else if(char == '{' || char == '[') {
cnt++;
}
out += char;
if(char == ',' || char == '{' || char == '[') {
out += nl + pad(tab * cnt * k, '', space);
}
if(char == ':') {
out += ' ';
}
}
return out;
}

Related

How can I split a string without losing the separator and without regex?

I have a string similar to "<p></p>". Now, I want to split this string, so I have 2 tags. If I do
var arr = "<p></p>".split("><") , I get an array that looks like
["<p", "/p>"]
Is there a simple way to keep the separator in this split? NOT a REGEX (Not a dupe) I want :
["<p>","</p>"]
Since javascript regex doesn't support look behind assertion it's not possible with String#split method. Use String#match method to get the complete string.
var arr = "<p></p>".match(/[\s\S]+?>(?=<|$)/g)
console.log(arr)
Without regex and using split you can do something like this.
var arr = "<p></p>".split('><').map(function(v, i, arr1) {
if (i != 0)
v = '<' + v;
if (i < arr1.length - 1)
v += '>';
return v;
})
// using ternary
var arr1 = "<p></p>".split('><').map(function(v, i, arr1) {
return (i != 0 ? '<' : '') + v + (i < arr1.length - 1 ? '>' : '');
})
console.log(arr);
console.log(arr1);
To do this without a regular expression, you'll need some kind of parser. Inspect every character, build up chunks and store them in an array. You may then want to process the bits, looking for tokens or doing other processing. E.g.
/* Break string into chunks of <...>, </...> and anything in between.
** #param {string} s - string to parse
** #returns {Array} chunks of string
*/
function getChunks(s) {
var parsed = [];
var limit = s.length - 1;
s.split('').reduce(function(buffer, char, i) {
var startTag = char == '<';
var endTag = char == '/';
var closeTag = char == '>';
if (startTag) {
if (buffer.length) {
parsed.push(buffer);
}
buffer = char;
} else if (endTag) {
buffer += char;
} else if (closeTag) {
parsed.push(buffer + char)
buffer = '';
} else {
buffer += char;
}
if (i == limit && buffer.length) {
parsed.push(buffer);
}
return buffer;
}, '');
return parsed;
}
['<p></p>',
'<div>More complex</div>',
'<span>broken tag</sp'
].forEach(function(s){
console.log(s + ' => [' + getChunks(s) + ']')
});
Note that this is very simple and just looks for <...> and </...> where ... can be anything.

Can I make a JSON-stringified object have a field whose value is a double in Javascript?

I am POSTing JSON from my Javascript application to this API that behaves differently if you send it doubles vs. ints. I just use JSON.stringify to build my request bodies. I always want to send doubles. But when I have Javascript numbers that are integral, JSON.stringify does this:
> JSON.stringify({x: 1.0});
'{"x":1}'
That unadorned 1 goes to the API where the other server thinks it's an int, and I get the integer behavior, which I don't want. Is there any known hack to get a double in my JSON in Javascript?
JSON (and JavaScript in general) don't distinguish between different numeric types; there's only "number". As such this is a bit outside the scope of JSON.stringify.
Here's a pretty awful workaround:
JSON.stringify({x: 1.0}).replace(
/("(?:[^"\\]|\\.)*")|[\[:,]\s*-?\d+(?![\d.eE])/g,
function (m0, m1) { return m1 || m0 + '.0'; }
)
This (rather big hammer) uses a regex to add .0 to all numbers that don't already have a . and are not part of a quoted string.
Another approach: build a custom version of JSON.stringify which will always output numbers with a decimal point.
This simply takes an example implementation from the Mozilla JSON documentation and modifies the line of code that handles numbers:
window.JSON.stringifyDecimal = (function(){
var toString = Object.prototype.toString;
var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; };
var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
return function stringify(value) {
if (value == null) {
return 'null';
} else if (typeof value === 'number') {
// Ensure decimal point is present
return isFinite(value) ? value.toString() + ( Number.isInteger( value ) ? '.0' : '' ) : 'null';
} else if (typeof value === 'boolean') {
return value.toString();
} else if (typeof value === 'object') {
if (typeof value.toJSON === 'function') {
return stringify(value.toJSON());
} else if (isArray(value)) {
var res = '[';
for (var i = 0; i < value.length; i++)
res += (i ? ', ' : '') + stringify(value[i]);
return res + ']';
} else if (toString.call(value) === '[object Object]') {
var tmp = [];
for (var k in value) {
if (value.hasOwnProperty(k))
tmp.push(stringify(k) + ': ' + stringify(value[k]));
}
return '{' + tmp.join(', ') + '}';
}
}
return '"' + value.toString().replace(escRE, escFunc) + '"';
};
})();
With JSON, you have two parties: The writer and the reader. In your case, the writer is your request and you're using JSON.stringify to generate the JSON string, and the reader is the API (which I don't know what it uses to parse the string back to a JSON object). You need both sides to be able to understand that 1.0 should stay as is because it's a double not an integer.
JSON string itself is just text and keeps whatever you give it as is. It is the JSON.stringify that is converting 1.0 to 1, so you can easily create your JSON string manually instead of using JSON.stringify:
var text = JSON.stringify({x: 1.0}); //JSON string will be {"x": 1}
var text = '{"x": 1.0}'; //JSON string will be exactly {"x": 1.0}
However, even if you do that, you need the other side (i.e. the API) to parse the value 1.0 as double, not an integer. Is that under your control? For example, the JavaScript JSON.parse function will parse the 1.0 as 1 exactly like JSON.stringify does:
var obj = JSON.parse('{"x": 1.0}');
alert(obj.x); //It prints 1, even though we gave it 1.0

WEIRD: Javascript string.split() and forloop split prepends mysterious comma ',' to resulting string

So I am messing around with JS Objects, trying stuff out. I am taking a GET request, was JSON, now object. I selec the .api path. I want to traverse the object and store it's name so I can pull more JSON for a ORM expirement. Doesn't matter really. But here is the JSON:
var fakeRESTResponse = function() {
return {
"swaggerVersion": "1.2",
"apiVersion": "1.0.0",
"apis": [{
"path": "/Users"
}, {
"path": "/Skills"
}, {
"path": "/Resumes"
}],
"info": {}
};
};
function createSubstr(strin, thechar) {
var substr = [];
for (var i = 0; i < strin.length; i++) {
var str = ' ';
if (strin[i] === thechar) {
console.log("found first match" + strin + ' str[i] ' + strin[i] + ' thechar ' + thechar + ' str: ' + str);
i++;
while (strin[i] !== thechar && strin[i] !== ',' && i < strin.length && strin[i] !== '"') {
if (str === ' ') str = strin[i];
else str += strin[i];
console.log(str + " : " + strin[i]);
i++;
}
substr.push(str);
str = ' ';
}
}
console.log('Return substr ' + substr);
return substr;
}
That was returned from the server. After trying .split, as you will see below, I built a manual function and some weird stuff:
http://codepen.io/willbittner/pen/aObVWG
That code pen above shows the .split('/') function returning the weird objects:
expected: ['Users','Skills','Resumes']
.split: [',Users',',Skills',',Resumes']
Now, if I move the function:
substr.push(str);
str = ' ';
out to the next scope,
**
http://codepen.io/willbittner/pen/GJROEV
**
You get both the for loop and the .split() producing that whack comma.
So I know it has something to do (likely) with the values in the loop changing before they are accessed because I am overlooking something, but I just can't figure out what causes this!!
* Note- I don't want to fix it, so plz don't respond with a different way of doing it. I want to know why this happens. *
To me- if there was a character APPENDED on the end, that would be more acceptable, but what bug in my code PREPENDS a string, as well as SHIFTS it! No Characters were lost! It shifted it as well I guess lol.

Create a string of variable length, filled with a repeated character

So, my question has been asked by someone else in it's Java form here: Java - Create a new String instance with specified length and filled with specific character. Best solution?
. . . but I'm looking for its JavaScript equivalent.
Basically, I'm wanting to dynamically fill text fields with "#" characters, based on the "maxlength" attribute of each field. So, if an input has has maxlength="3", then the field would be filled with "###".
Ideally there would be something like the Java StringUtils.repeat("#", 10);, but, so far, the best option that I can think of is to loop through and append the "#" characters, one at a time, until the max length is reached. I can't shake the feeling that there is a more efficient way to do it than that.
Any ideas?
FYI - I can't simply set a default value in the input, because the "#" characters need to clear on focus, and, if the user didn't enter a value, will need to be "refilled" on blur. It's the "refill" step that I'm concerned with
The best way to do this (that I've seen) is
var str = new Array(len + 1).join( character );
That creates an array with the given length, and then joins it with the given string to repeat. The .join() function honors the array length regardless of whether the elements have values assigned, and undefined values are rendered as empty strings.
You have to add 1 to the desired length because the separator string goes between the array elements.
Give this a try :P
s = '#'.repeat(10)
document.body.innerHTML = s
ES2015 the easiest way is to do something like
'X'.repeat(data.length)
X being any string, data.length being the desired length.
see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
Unfortunately although the Array.join approach mentioned here is terse, it is about 10X slower than a string-concatenation-based implementation. It performs especially badly on large strings. See below for full performance details.
On Firefox, Chrome, Node.js MacOS, Node.js Ubuntu, and Safari, the fastest implementation I tested was:
function repeatChar(count, ch) {
if (count == 0) {
return "";
}
var count2 = count / 2;
var result = ch;
// double the input until it is long enough.
while (result.length <= count2) {
result += result;
}
// use substring to hit the precise length target without
// using extra memory
return result + result.substring(0, count - result.length);
};
This is verbose, so if you want a terse implementation you could go with the naive approach; it still performs betweeb 2X to 10X better than the Array.join approach, and is also faster than the doubling implementation for small inputs. Code:
// naive approach: simply add the letters one by one
function repeatChar(count, ch) {
var txt = "";
for (var i = 0; i < count; i++) {
txt += ch;
}
return txt;
}
Further information:
Run speed test in your own browser
Full source code of speed test
Speed test results
I would create a constant string and then call substring on it.
Something like
var hashStore = '########################################';
var Fiveup = hashStore.substring(0,5);
var Tenup = hashStore.substring(0,10);
A bit faster too.
http://jsperf.com/const-vs-join
A great ES6 option would be to padStart an empty string. Like this:
var str = ''.padStart(10, "#");
Note: this won't work in IE (without a polyfill).
Version that works in all browsers
This function does what you want, and performs a lot faster than the option suggested in the accepted answer :
var repeat = function(str, count) {
var array = [];
for(var i = 0; i <= count;)
array[i++] = str;
return array.join('');
}
You use it like this :
var repeatedCharacter = repeat("a", 10);
To compare the performance of this function with that of the option proposed in the accepted answer, see this Fiddle and this Fiddle for benchmarks.
Version for moderns browsers only
In modern browsers, you can now also do this :
var repeatedCharacter = "a".repeat(10) };
This option is even faster. However, unfortunately it doesn't work in any version of Internet explorer.
The numbers in the table specify the first browser version that fully supports the method :
For Evergreen browsers, this will build a staircase based on an incoming character and the number of stairs to build.
function StairCase(character, input) {
let i = 0;
while (i < input) {
const spaces = " ".repeat(input - (i+1));
const hashes = character.repeat(i + 1);
console.log(spaces + hashes);
i++;
}
}
//Implement
//Refresh the console
console.clear();
StairCase("#",6);
You can also add a polyfill for Repeat for older browsers
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw new TypeError('can\'t convert ' + this + ' to object');
}
var str = '' + this;
count = +count;
if (count != count) {
count = 0;
}
if (count < 0) {
throw new RangeError('repeat count must be non-negative');
}
if (count == Infinity) {
throw new RangeError('repeat count must be less than infinity');
}
count = Math.floor(count);
if (str.length == 0 || count == 0) {
return '';
}
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28) {
throw new RangeError('repeat count must not overflow maximum string size');
}
var rpt = '';
for (;;) {
if ((count & 1) == 1) {
rpt += str;
}
count >>>= 1;
if (count == 0) {
break;
}
str += str;
}
// Could we try:
// return Array(count + 1).join(this);
return rpt;
}
}
Based on answers from Hogan and Zero Trick Pony. I think this should be both fast and flexible enough to handle well most use cases:
var hash = '####################################################################'
function build_string(length) {
if (length == 0) {
return ''
} else if (hash.length <= length) {
return hash.substring(0, length)
} else {
var result = hash
const half_length = length / 2
while (result.length <= half_length) {
result += result
}
return result + result.substring(0, length - result.length)
}
}
You can use the first line of the function as a one-liner if you like:
function repeat(str, len) {
while (str.length < len) str += str.substr(0, len-str.length);
return str;
}
I would do
Buffer.alloc(length, character).toString()
If it's performance you need (prior to ES6), then a combination of substr and a template string is probably best. This function is what I've used for creating space padding strings, but you can change the template to whatever you need:
function strRepeat(intLen, strTemplate) {
strTemplate = strTemplate || " ";
var strTxt = '';
while(intLen > strTemplate.length) {
strTxt += strTemplate;
intLen -= strTemplate.length;
}
return ((intLen > 0) ? strTxt + strTemplate.substr(0, intLen) : strTxt);
}

Get textual (string) version of an object - displaying in the browser for debugging purposes [duplicate]

I'm trying to find a way to "pretty print" a JavaScript data structure in a human-readable form for debugging.
I have a rather big and complicated data structure being stored in JS and I need to write some code to manipulate it. In order to work out what I'm doing and where I'm going wrong, what I really need is to be able to see the data structure in its entirety, and update it whenever I make changes through the UI.
All of this stuff I can handle myself, apart from finding a nice way to dump a JavaScript data structure to a human-readable string. JSON would do, but it really needs to be nicely formatted and indented. I'd usually use Firebug's excellent DOM dumping stuff for this, but I really need to be able to see the entire structure at once, which doesn't seem to be possible in Firebug.
Use Crockford's JSON.stringify like this:
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...
Variable text would look like this:
[
"e",
{
"pluribus": "unum"
}
]
By the way, this requires nothing more than that JS file - it will work with any library, etc.
I wrote a function to dump a JS object in a readable form, although the output isn't indented, but it shouldn't be too hard to add that: I made this function from one I made for Lua (which is much more complex) which handled this indentation issue.
Here is the "simple" version:
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;
}
I will look at improving it a bit.
Note 1: To use it, do od = DumpObject(something) and use od.dump. Convoluted because I wanted the len value too (number of items) for another purpose. It is trivial to make the function return only the string.
Note 2: it doesn't handle loops in references.
EDIT
I made the indented version.
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$/, "");
}
Choose your indentation on the line with the recursive call, and you brace style by switching the commented line after this one.
... I see you whipped up your own version, which is good. Visitors will have a choice.
You can use the following
<pre id="dump"></pre>
<script>
var dump = JSON.stringify(sampleJsonObject, null, 4);
$('#dump').html(dump)
</script>
In Firebug, if you just console.debug ("%o", my_object) you can click on it in the console and enter an interactive object explorer. It shows the entire object, and lets you expand nested objects.
For Node.js, use:
util.inspect(object, [options]);
API Documentation
For those looking for an awesome way to see your object, check prettyPrint.js
Creates a table with configurable view options to be printed somewhere on your doc. Better to look than in the console.
var tbl = prettyPrint( myObject, { /* options such as maxDepth, etc. */ });
document.body.appendChild(tbl);
I'm programming in Rhino and I wasn't satisfied with any of the answers that were posted here. So I've written my own pretty printer:
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)
}
The output looks like this:
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: []
}
}
I've also posted it as a Gist here for whatever future changes may be required.
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')
])
becomes
[
[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">
]
QUnit (Unit-testing framework used by jQuery) using slightly patched version of jsDump.
JSON.stringify() is not best choice on some cases.
JSON.stringify({f:function(){}}) // "{}"
JSON.stringify(document.body) // TypeError: Converting circular structure to JSON
Taking PhiLho's lead (thanks very much :)), I ended up writing my own as I couldn't quite get his to do what I wanted. It's pretty rough and ready, but it does the job I need. Thank you all for the excellent suggestions.
It's not brilliant code, I know, but for what it's worth, here it is. Someone might find it useful:
// 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
}
For anyone checking this question out in 2021 or post-2021
Check out this Other StackOverflow Answer by hassan
TLDR:
JSON.stringify(data,null,2)
here the third parameter is the tab/spaces
This is really just a comment on Jason Bunting's "Use Crockford's JSON.stringify", but I wasn't able to add a comment to that answer.
As noted in the comments, JSON.stringify doesn't play well with the Prototype (www.prototypejs.org) library. However, it is fairly easy to make them play well together by temporarily removing the Array.prototype.toJSON method that prototype adds, run Crockford's stringify(), then put it back like this:
var temp = Array.prototype.toJSON;
delete Array.prototype.toJSON;
$('result').value += JSON.stringify(profile_base, null, 2);
Array.prototype.toJSON = temp;
I thought J. Buntings response on using JSON.stringify was good as well. A an aside, you can use JSON.stringify via YUIs JSON object if you happen to be using YUI. In my case I needed to dump to HTML so it was easier to just tweak/cut/paste PhiLho response.
function dumpObject(obj, indent)
{
var CR = "<br />", SPC = " ", 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;
}
Lots of people writing code in this thread, with many comments about various gotchas. I liked this solution because it seemed complete and was a single file with no dependencies.
browser
nodejs
It worked "out of the box" and has both node and browser versions (presumably just different wrappers but I didn't dig to confirm).
The library also supports pretty printing XML, SQL and CSS, but I haven't tried those features.
A simple one for printing the elements as strings:
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);
My NeatJSON library has both Ruby and JavaScript versions. It is freely available under a (permissive) MIT License. You can view an online demo/converter at:
http://phrogz.net/JS/neatjson/neatjson.html
Some features (all optional):
Wrap to a specific width; if an object or array can fit on the line, it is kept on one line.
Align the colons for all keys in an object.
Sort the keys to an object alphabetically.
Format floating point numbers to a specific number of decimals.
When wrapping, use a 'short' version that puts the open/close brackets for arrays and objects on the same line as the first/last value.
Control the whitespace for arrays and objects in a granular manner (inside brackets, before/after colons and commas).
Works in the web browser and as a Node.js module.
flexjson includes a prettyPrint() function that might give you what you want.

Categories

Resources