本以为这个问题挺简单的?

本来以为这个问题挺简单的

复制一个对象粘贴到输入框里

获取值的时候把它转成JSON字符串

复制的对象数据是这样的

{
            "q": "710022883",
            "id": "333",
            "extra": [
                {
                    "extra": "23",
                    "qty": 1,
                    "id": "222"
                },
                {
                    "id": "2333",
                    "qty": 1,
                    "extra": "222"
                }
            ],
            "qty": 1,
            "spec": "123",
}

粘贴到输入框里是这样的

{             "q": "710022883",             "id": "333",             "extra": [                 {                     "extra": "23",                     "qty": 1,                     "id": "222"                 },                 {                     "id": "2333",                     "qty": 1,                     "extra": "222"                 }             ],             "qty": 1,             "spec": "123", }

怎么把它转成下面这种格式呢

{"q":"710022883","id":"333","extra":[{"extra":"23","qty":1,"id":"222"},{"id":"2333","qty":1,"extra":"222"}],"qty":1,"spec":"123",}

就是这个地址粘贴进去,点压缩的效果。
https://www.sojson.com/yasuo....

阅读 2k
2 个回答

JSON 压缩,即去除多余空格

首先,你这个数据格式不符合 JSON 规范,JSON 规定不允许有尾随逗号

"spec": "123", // 这里不允许有逗号

把这个逗号去了,然后用 JSON.stringify(JSON.parse(data)) 即可压缩(去除多余空格)

JSON.stringify(JSON.parse(`{
            "q": "710022883",
            "id": "333",
            "extra": [
                {
                    "extra": "23",
                    "qty": 1,
                    "id": "222"
                },
                {
                    "id": "2333",
                    "qty": 1,
                    "extra": "222"
                }
            ],
            "qty": 1,
            "spec": "123"
}`))

题外话:
之所以你那个网站能压缩,是因为它并没有遵循 JSON 规范,校验 JSON 格式,只是自己对字符串进行简单处理,以下是它的源码

text = text.split("\n").join(" ");
var t = [];
var inString = false;
for (var i = 0, len = text.length; i < len; i++) {
  var c = text.charAt(i);
  if (inString && c === inString) {
      if (text.charAt(i - 1) !== '\\') {
          inString = false
      }
  } else if (!inString && (c === '"' || c === "'")) {
      inString = c
  } else if (!inString && (c === ' ' || c === "\t")) {
      c = ''
  }
  t.push(c)
}
text = t.join('')

像这样写,不遵循 JSON 规范,会导致一些 bug,举个反例:

{
    "path": "C:\\Program Files\\",
    "name": "Microsoft SQL Server"
}

它的压缩结果是

{"path":"C:\\Program Files\\",     "name": "MicrosoftSQLServer" } 

正确是

{"path":"C:\\Program Files\\","name":"Microsoft SQL Server"}

能正确压缩 JSON 的网站:


扩展

JSON 解析除了用 JSON.parse() 还可以用 @唯一丶 提议的 JSON5JSON5.parse(),JSON5 兼容 JSON,且允许尾随逗号

console.log(JSON.stringify(JSON5.parse(String.raw`{
    "path": "C:\\Program Files\\",
    "name": "\"Microsoft SQL Server\"",
    "": "",
}`)))
// {"path":"C:\\Program Files\\","name":"\"Microsoft SQL Server\"","":""}

如果数据量很大,要慎用 JSON5,因为 JSON5.parse() 是 JS 实现的,性能远不及内置原生代码实现的 JSON.parse(),一比十几甚至几十

当然也不是非要先解析再序列化,只要遵循 JSON 规范正确去除空白字符即可,主要是要绕过 JSON 字符串内部的空格,但如果自己写循环判断,性能会不如 JSON.stringify(JSON.parse(text)) ,可以利用正则表达式

const compactJSON = text => {
  let res = ''
  for (const m of text.match(/(?:[^\t\n\r "]+|"(?:\\.|[^\\])*?")+/g)) res += m
  return res
}
// reduce 拼接,性能一样:const compactJSON = text => text.match(/(?:[^\t\n\r "]+|"(?:\\.|[^\\])*?")+/g).reduce((a, b) => a + b)
// concat 拼接,性能一样:const compactJSON = text => ''.concat(...text.match(/(?:[^\t\n\r "]+|"(?:\\.|[^\\])*?")+/g))
// 不用 text.match(re).join('') 是因为 join('') 性能偏低

console.log(compactJSON(String.raw`{
    "path": "C:\\Program Files\\",
    "name": "\"Microsoft SQL Server\"",
    "": "",
}`))
// {"path":"C:\\Program Files\\","name":"\"Microsoft SQL Server\"","":"",}

可以看到去了也仅去了在 JSON 字符串外部的空白字符,剩下的字符保持不变,尾随逗号也在

因为正则表达式也是内置原生代码实现的,性能也很高,经过测试 compactJSON(text)JSON.stringify(JSON.parse(text)) 还要快 \( 60\% \) 左右

测试数据:

const text = String.raw`[{
    "path": "C:\\Program Files\\",
    "name": "\"Microsoft SQL Server\"",
    "": ""
},
{
            "q": "710022883",
            "id": "333",
            "extra": [
                {
                    "extra": "23",
                    "qty": 1,
                    "id": "222"
                },
                {
                    "id": "2333",
                    "qty": 1,
                    "extra": "222"
                }
            ],
            "qty": 1,
            "spec": "123"
}]`

在我电脑的 Chrome 上分别执行 \( 10^6 \) 次
JSON.stringify(JSON.parse(text)) 耗时大约 \( 4 \) 秒
compactJSON(text) 耗时大约 \( 2.5 \) 秒

??不就是stringiry吗?

JSON.stringify({
            "q": "710022883",
            "id": "333",
            "extra": [
                {
                    "extra": "23",
                    "qty": 1,
                    "id": "222"
                },
                {
                    "id": "2333",
                    "qty": 1,
                    "extra": "222"
                }
            ],
            "qty": 1,
            "spec": "123",
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题