11
\$\begingroup\$

Jason has a big JSON but it's unreadable, so he needs to prettify it.

Formatting Spec

The JSON has 4 different types:

  • Numbers; Just 0-9
  • Strings; Double quoted " strings escaped with \
  • Arrays; Delimited by [], with items separated by ,, items can be any of these types
  • Objects; Delimited by {}, format is key: value where key is a string and value is any of these types

Spacing

  • Arrays should have exactly one space after the commas between items
  • Objects should have have just one space between the key and the value, after the :

Indentation

  • Each nesting level is indented 2 more than the previous
  • Each object key/value pair is always on its own line. Objects are indented
  • An array is indented across multiple lines if it contains another array or object. Otherwise the array remains on one line

Rules

  • Built-ins which trivialize this task are not allowed.
  • As always standard loopholes are disallowed

Examples

[1,2,3]
[1, 2, 3]
{"a":1,"b":4}
{
  "a": 1,
  "b": 4
}
"foo"
"foo"
56
56
{"a":[{"b":1,"c":"foo"},{"d":[2,3,4,1], "a":["abc","def",{"d":{"f":[3,4]}}]}]}
{
  "a": [
    {
      "b": 1,
      "c": "foo"
    },
    {
      "d": [2, 3, 4, 1],
      "a": [
        "abc",
        "def",
        {
          "d": {
            "f": [3, 4]
          }
        }
      ]
    }
  ]
}
[2,["foo123 ' bar \" baz\\", [1,2,3]]]
[
  2,
  [
    "foo123 ' bar \" baz\\",
    [1, 2, 3]
  ]
]
[1,2,3,"4[4,5]"]
[1, 2, 3, "4[4,5]"]
[1,2,3,{"b":["{\"c\":[2,5,6]}",4,5]}]
[
  1,
  2,
  3,
  {
    "b": ["{\"c\":[2,5,6]}", 4, 5]
  }
]
\$\endgroup\$
  • 1
    \$\begingroup\$ Are JSON parsing builtins allowed? \$\endgroup\$ – PurkkaKoodari Mar 1 '16 at 7:45
  • \$\begingroup\$ Can objects/arrays be empty? Can we still print a space after commas in arrays if they split over multiple lines? \$\endgroup\$ – Martin Ender Mar 1 '16 at 8:40
  • \$\begingroup\$ @MartinBüttner no, and yes \$\endgroup\$ – Downgoat Mar 1 '16 at 14:59
  • \$\begingroup\$ @Pietu1998 hm, I'm going to say no \$\endgroup\$ – Downgoat Mar 1 '16 at 14:59
  • \$\begingroup\$ Are language parser languages allowed? \$\endgroup\$ – Mama Fun Roll Mar 1 '16 at 16:27
1
\$\begingroup\$

JavaScript (ES6), 368 bytes

f=(s,r=[],i='',j=i+'  ',a=[])=>s<'['?([,,r[0]]=s.match(s<'0'?/("(?:\\.|[^"])*")(.*)/:/(\d+)(.*)/))[1]:s<'{'?(_=>{for(;s<']';s=r[0])a.push(f(s.slice(1),r,j));r[0]=s.slice(1)})()||/\n/.test(a)?`[
${j+a.join(`,
`+j)}
${i}]`:`[${a.join`, `}]`:(_=>{for(a=[];s<'}';s=r[0])a.push(f(s.slice(1),r,j)+': '+f(r[0].slice(1),r,j));r[0]=s.slice(1)})()||`{
${j+a.join(`,
`+j)}
${i}}`

Less golfed:

function j(s, r=[], i='') { // default to no indentation
    if (s < '0') { // string
        let a = s.match(/("(?:\\.|[^"])*")(.*)/);
        r[0] = a[2]; // pass the part after the string back to the caller
        return a[1];
    } else if (s < '[') { // number
        let a = s.match(/(\d+)(.*)/);
        r[0] = a[2]; // pass the part after the string back to the caller
        return a[1];
    } else if (s < '{') { // array
        let a = [];
        while (s < ']') { // until we see the end of the array
            s = s.slice(1);
            a.push(j(s, r, i + '  ')); // recurse with increased indentation
            s = r[0]; // retrieve the rest of the string
        }
        r[0] = s.slice(1); // pass the part after the string back to the caller
        if (/\n/.test(a.join())) { // array contained object
            return '[\n  ' + i + a.join(',\n  ' + i) + '\n' + i + ']';
        } else {
            return '[' + a.join(', ') + ']';
        }
    } else { // object
        let a = [];
        while (s < '}') { // until we see the end of the object
            s = s.slice(1);
            let n = j(s, r, i + '  ');
            s = r[0].slice(1);
            let v = j(s, r, i + '  ');
            a.push(n + ': ' + v);
            s = r[0]; // retrieve the rest of the string
        }
        r[0] = s.slice(1); // pass the part after the string back to the caller
        return '{\n  ' + i + a.join(',\n  ' + i) + '\n' + i + '}';
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.