2

How can I create a minimum-sized Javascript serialization of a Javascript object? Essentially a JSON.stringify with all unnecessary quotes removed. (Only basic JSON data types need to be supported, not Dates etc.)

For example, the JSON:

{
  "pi": 3.14,
  "e!": 4.26
}

would become:

{pi:3.14,"e!":4.26}

Edit: The result is not valid JSON, but is valid Javascript.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Sampo
  • 4,308
  • 6
  • 35
  • 51
  • 2
    This is not a proper JSON, since the quotes are *mandatory*. – VLAZ Oct 01 '19 at 19:42
  • 3
    `all unnecessary quotes` The spec says those quotes are very necessary. You are producing invalid JSON. –  Oct 01 '19 at 19:43
  • I am not producing JSON, I am producing Javascript. – Sampo Oct 01 '19 at 19:44
  • But you said JSON? – VLAZ Oct 01 '19 at 19:44
  • 2
    run it through a minifier? – ASDFGerte Oct 01 '19 at 19:44
  • 2
    Write you own `stringify` method using `Object.entries(obj)`. Still, this sounds like an XY problem, so why do you need this? And you should add your own attempt to the question. –  Oct 01 '19 at 19:44
  • 1
    The confusion on my end was caused by `a minimum-sized Javascript serialization`. Serialized JS is referred to as JSON. If you want to produce JS *code*, I'd amend that line accordingly. –  Oct 01 '19 at 19:46
  • 2
    use a js minifier. – Daniel A. White Oct 01 '19 at 19:49
  • Possible duplicate of [JSON.stringify without quotes on properties?](https://stackoverflow.com/questions/11233498/json-stringify-without-quotes-on-properties) – Taha Paksu Oct 01 '19 at 19:49
  • @TahaPaksu not a (complete) dupe. It only covers removing quotes from keys but doesn't minimise the space needed, nor does it (necessarily) check if the unquoted key is syntactically correct. – VLAZ Oct 01 '19 at 19:53
  • Yea you are right, but the answers given there with a slight modification leads to the answer. Modifying the regexes there to exclude non-alphanumeric characters, and removing the spaces between keys and values should be enough. Well, I might give an answer.. – Taha Paksu Oct 01 '19 at 19:58
  • 4
    I'm still not sure why OP doesn't want to use a minifier. – VLAZ Oct 01 '19 at 19:59
  • `.replace(/"(\w+)":/g,"$1:")` will kill quotes on valid keys. – dandavis Oct 01 '19 at 20:09

1 Answers1

1

Copied from https://stackoverflow.com/a/11233515/916000 and modified:

function stringify(obj_from_json) {
  if (typeof obj_from_json !== "object") {
    return JSON.stringify(obj_from_json);
  } else {
    if (Array.isArray(obj_from_json)) {
      // if the array contains an object
      var arr = [];
      for (var i = 0, len = obj_from_json.length; i < len; i++) {
        arr.push(stringify(obj_from_json[i]));
      }
      return "[" + arr.join(",") + "]";
    } else {
      var props = Object
        .keys(obj_from_json)
        .map(function(key) {
          return (new RegExp(/^[1-9a-zA-Z_$][a-zA-Z0-9_$.]*$/).test(key) ? key : "\"" + key + "\"") + ":" + stringify(obj_from_json[key]);
        }).join(",");
      return "{" + props + "}";
    }
  }
}


console.log(stringify({
  "pi": 3.14,
  "e!": 4.26
}));

console.log(stringify([{
  "adjacencies": [{
    "nodeTo": "graphnode2",
    "nodeFrom": "graphnode1",
    "data": {
      "$color": "#557EAA"
    }
  }],
  "data": {
    "$color": "#EBB056",
    "$type": "triangle",
    "$dim": 9
  },
  "id": "graphnode1",
  "name": "graphnode1"
}, {
  "adjacencies": [],
  "data": {
    "$color": "#EBB056",
    "$type": "triangle",
    "$dim": 9
  },
  "id": "graphnode2",
  "name": "graphnode2"
}]));

console.log(stringify({1: 2}));
console.log(stringify({"000": 42}));
console.log(stringify({1.26: 42}));

Edit: Added object array support. Edit: Fixed array conversion.

Taha Paksu
  • 15,371
  • 2
  • 44
  • 78