Json - 字符串化,使数组在一行上
Posted
技术标签:
【中文标题】Json - 字符串化,使数组在一行上【英文标题】:Json - stringify so that arrays are on one line 【发布时间】:2011-10-19 18:05:09 【问题描述】:是否可以将 JSON 对象字符串化为如下所示,数组在一行中 - 不缩进
"Repeat":
"Name": [["Top_level","All"],[[1,1]]],
"Link": [["Top_level"],[[1,1]]]
,
"Delete": ["Confirm","Cancel"],
"Move": ["Up","Down"],
"Number": ["Ascending","Descending"]
【问题讨论】:
【参考方案1】:试试这个:
var obj = "Repeat": "Name":[["Top_level","All"],[[1,1]]],"Link": [["Top_level"],[[1,1]]],"Delete": ["Confirm","Cancel"],"Move": ["Up","Down"],"Number": ["Ascending","Descending"];
JSON.stringify(obj,function(k,v)
if(v instanceof Array)
return JSON.stringify(v);
return v;
,2);
结果:
"
"Repeat":
"Name": "[[\"Top_level\",\"All\"],[[1,1]]]",
"Link": "[[\"Top_level\"],[[1,1]]]"
,
"Delete": "[\"Confirm\",\"Cancel\"]",
"Move": "[\"Up\",\"Down\"]",
"Number": "[\"Ascending\",\"Descending\"]"
"
【讨论】:
谢谢,看起来应该是这样。我会适时试一试。 k 是做什么的? k 和 v 是传递给该函数的对象的键/值,在这种情况下 k 不做任何事情 数组以单个字符串的形式出现;有没有同样聪明的方法将它们返回到数组?如果是这样,你的答案肯定会得到滴答声 输出如下:` "images": "[\"2\",\"3\",\"4\",\"5\",\"6\" ,\"7\"]"` 这部分有点棘手,我在实现它时所做的是用正则表达式去除引号和反斜杠。至于数组,您可以创建一个递归方法,每次检测到数组时循环遍历并将其附加在输出字符串的末尾。从这里开始可能会有点乱。【参考方案2】:从ericbowden 和bigp 得到答案,我生成了以下函数,该函数允许我漂亮地打印 JSON,同时将数组保持在一行,并将数组保持为数组形式,而不是将其转换为字符串。
function prettyPrintArray(json)
if (typeof json === 'string')
json = JSON.parse(json);
output = JSON.stringify(json, function(k,v)
if(v instanceof Array)
return JSON.stringify(v);
return v;
, 2).replace(/\\/g, '')
.replace(/\"\[/g, '[')
.replace(/\]\"/g,']')
.replace(/\"\/g, '')
.replace(/\\"/g,'');
return output;
【讨论】:
感谢您的回答 - 这很好用。在这里,我调整了您的函数以通过 JSLint:const prettyPrintArray = obj => JSON.stringify( obj, (key, val) => (val instanceof Array) ? JSON.stringify(val) : val, 2).replace(/\\/g, '').replace(/\[/g, '[').replace(/\]/g,']').replace(/\/g, '').replace(/\/g,'');
【参考方案3】:
如果您打算将短数组显示为单行,请考虑使用json-stringify-pretty-compact。它产生如下结果:
"bool": true,
"short array": [1, 2, 3],
"long array": [
"x": 1, "y": 2,
"x": 2, "y": 1,
"x": 1, "y": 1,
"x": 2, "y": 2
]
【讨论】:
一旦你开始使用它就可以很好地工作。虽然这是一个奇怪的过程 - 或者我不知道我在做什么......它可以使用 npm 轻松安装。之后,要使其正常工作,您的脚本标签需要指向“index.js”(没有 json-stringify-pretty-compact js 文件)。然后你必须注释掉最后一行,像这样://module.exports = stringify
。然后你可以用它来代替 JSON.stringify,像这样:stringify(jSONObject, null, 2)
。事实上,它确实让 JSON 看起来更好。【参考方案4】:
我采取的另一种方法:
obj => JSON.stringify(obj, (k,v) => Array.isArray(v) ? JSON.stringify(v) : v, 2)
.replace(/"\[[^"\]]*]"/g, r => JSON.stringify(JSON.parse(r)).substr(1).slice(0,-1))
*Array 不能包含字符串(注意正则表达式中的“不包含”),如果您删除它,它将捕获以下键值:
"[": "[1,2,3,4]",
2020-03 更新 - 我制定了一个更稳定的解决方案
const obj =
"first_name": "John",
"last_name": "Smith",
"age": 21,
"hobbies": [ "programming", "workout", null, undefined, 24, "\"has double quotes\"" ],
"nested":
"arr": [ "one", "two", "three" ],
,
"nested_arr": [
"first as string",
"latin": [ "alpha", "beta", "[gamma]" ]
,
null
]
;
const stringify = (obj, indent = 2) =>
JSON.stringify(obj, (key, value) =>
if (Array.isArray(value) && !value.some(x => x && typeof x === 'object'))
return `\uE000$JSON.stringify(value.map(v => typeof v === 'string' ? v.replace(/"/g, '\uE001') : v))\uE000`;
return value;
, indent).replace(/"\uE000([^\uE000]+)\uE000"/g, match => match.substr(2, match.length - 4).replace(/\\"/g, '"').replace(/\uE001/g, '\\\"'));
console.log(stringify(obj));
【讨论】:
你认为它会得到这样的结果吗:www.glasier.hk - select JSON 对于通用美化,我建议使用@Piotr Migdal 建议的第三方库【参考方案5】:试试这个:
JSON.stringify(obj,function(k,v)
if(v instanceof Array)
return JSON.stringify(v);
return v;
,4)
.replace(/"\[/g, '[')
.replace(/\]"/g, ']')
.replace(/\\"/g, '"')
.replace(/""/g, '"');
【讨论】:
我试过了,但这不适用于多级对象【参考方案6】:一个老问题的另一个现代答案:看看FracturedJson。该链接会将您带到 Web 版本,但它可以作为命令行应用程序以及用于 .NET 和 JS 的库。
FracturedJson 将内联数组/对象,只要它们既不太长也不太复杂。它同样可以将数组拆分为多行,每行有多个项目。
这是一个使用默认设置的示例,但您可以将它们调整为最适合您的数据的设置。
"SimpleItem": 77,
"ComplexObject":
"Subthing1": "X": 55, "Y": 19, "Z": -4,
"Subthing2": "Q": null, "W": [-2, -1, 0, 1] ,
"Distraction": [[], null, null]
,
"ShortArray": ["blue", "blue", "orange", "gray"],
"LongArray": [
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73,
79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157,
163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241,
251, 257, 263, 269, 271, 277, 281, 283, 293
],
"LongArray2": [
[19, 2],
[3, 8],
[14, 0],
[9, 9],
[9, 9],
[0, 3],
[10, 1],
[9, 1],
[9, 2],
[6, 13],
[18, 5],
[4, 11],
[12, 2]
]
披露:我是 FracturedJson 的作者。它是在 MIT 许可下开源的。
【讨论】:
我认为这是最好的解决方案。谢谢!!【参考方案7】:请注意,这使用lodash
来检测数组和对象,这是另一种将“叶子”对象保持在一行上的方法:
_.jsonPretty = function(obj, indent)
if(!indent) indent = 2;
return JSON.stringify(obj, function(k,v)
//Check if this is a leaf-object with no child Arrays or Objects:
for(var p in v)
if(_.isArray(v[p]) || _.isObject(v[p]))
return v;
return JSON.stringify(v);
//Cleanup the escaped strings mess the above generated:
, indent).replace(/\\/g, '')
.replace(/\"\[/g, '[')
.replace(/\]\"/g,']')
.replace(/\"\/g, '')
.replace(/\\"/g,'');
;
然后像这样使用它:
_.jsonPretty(yourObjectToStringify);
这是一个示例之前...
"type": "light-item",
"name": "Waiting",
"ringSeqLooping": true,
"ringSeqHoldLast": false,
"ringSteps": [
"type": "light-step",
"time": 1,
"audioClipName": "Off",
"audioVolume": 1,
"lights": [
"state": "FadeOn",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
]
,
"type": "light-step",
"time": "0.5",
"audioClipName": "Off",
"audioVolume": 1,
"lights": [
"state": "FadeOff",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
]
],
"stripSeqLooping": true,
"stripSeqHoldLast": false,
"stripSteps": [
"type": "light-step",
"time": "2",
"audioClipName": "Off",
"audioVolume": 1,
"lights": [
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "FadeOn",
"color": "#fff"
,
"state": "FadeOn",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
]
,
"type": "light-step",
"time": "2",
"audioClipName": "Off",
"audioVolume": 1,
"lights": [
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "FadeOff",
"color": "#fff"
,
"state": "FadeOff",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
,
"state": "Off",
"color": "#fff"
]
]
...和之后:
"type": "light-item",
"name": "Waiting",
"ringSeqLooping": "true",
"ringSeqHoldLast": "false",
"ringSteps": [
"type": "light-step",
"time": "1",
"audioClipName": "Off",
"audioVolume": "1",
"lights": [
"state":"FadeOn","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff"
]
,
"type": "light-step",
"time": "0.5",
"audioClipName": "Off",
"audioVolume": "1",
"lights": [
"state":"FadeOff","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff"
]
],
"stripSeqLooping": "true",
"stripSeqHoldLast": "false",
"stripSteps": [
"type": "light-step",
"time": "2",
"audioClipName": "Off",
"audioVolume": "1",
"lights": [
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"FadeOn","color":"#fff",
"state":"FadeOn","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff"
]
,
"type": "light-step",
"time": "2",
"audioClipName": "Off",
"audioVolume": "1",
"lights": [
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"FadeOff","color":"#fff",
"state":"FadeOff","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff",
"state":"Off","color":"#fff"
]
]
【讨论】:
呃......我刚才确实注意到了一些缺陷(特别是布尔值和数字),它在它周围加上了双引号。我想由您决定是否可以安全地对整个 JSON 字符串进行更多全局替换以消除这些边缘情况。【参考方案8】:这是我制定的一个解决方案,可以作为做类似事情的基础:
function labTab(ind)
var tab,com,a;
tab = "\t";
com = [];
for(a = 0; a < ind; a+=1)
com.push(tab)
return com.join("");
function nsetEntry(tab,o,obj)
return tab + '"'+ o + '":' + JSON.stringify(obj[o]);
function nsetObject(tab,o,obj,arr,ind)
var start;
start = tab + '"'+ o + '":';
return [start,nsetConstructor(obj[o],arr,ind)].join("\n") + "\n" + tab +"";
function nsetConstructor(obj,arr,ind)
var narr,tab,o,entry;
narr = [];
ind += 1;
tab = labTab(ind);
for(o in obj)
if(obj[o].constructor === Object)
entry = nsetObject(tab,o,obj,arr,ind);
narr.push(entry);
else
entry = nsetEntry(tab,o,obj);
narr.push(entry);
return narr.join(",\n");
function nsetLevels(obj,arr,ind)
var o,start,tab;
tab = labTab(ind);
for(o in obj)
if(obj[o].constructor === Object)
entry = nsetObject(tab,o,obj,arr,ind);
arr.push(entry);
else
entry = nsetEntry(tab,o,obj);
arr.push(entry);
return arr.join(",\n");
function nsetSave()
var json,o,ind,tab,obj,start,head,tail;
json = [];
for(o in nset)
ind = 1;
tab = labTab(ind);
start = tab + '"'+ o + '":';
ind = 2;
tab = labTab(ind);
obj = nset[o];
json.push([start,nsetLevels(obj,[],ind)].join("\n"))
head = "\n";
tail = "\n\t\n"
FW.Write([head,json.join("\n\t,\n"),tail].join(""),"xset.json")
由于一些成员下降了五个级别,我无法弄清楚如何进行替换,所以我重新创建了整个东西。解决方案不是那么热门,但我得到了我想要实现的目标 - 示例如下:
"Key":
"Label":
"Change":["Input"],
"Repeat":
"Name":[["Top_level","All"],[[1,1]]],
"Link":[["Top_level"],[[1,1]]]
,
"Delete":["Confirm","Cancel"],
"Move":["Up","Down"],
"Number":["Ascending","Descending"]
,
"Class":
"Change":["Input"]
,
【讨论】:
【参考方案9】:我对我的应用程序的配置文件使用 JSON 格式。它们非常不同且足够大,因此需要不同的格式规则以使它们看起来更好和可读。不幸的是,提供的答案不够灵活,所以我自己实现了一个名为 perfect-json 的实现来美化 JSON。
考虑你想像这样格式化问题中的对象:
"Repeat":
"Name": [
["Top_level", "All"],
[[1, 1]]
],
"Link": [
["Top_level"],
[[1, 1]]
]
,
"Delete": ["Confirm", "Cancel"],
"Move": ["Up", "Down"],
"Number": [
"Ascending",
"Descending"
]
用perfect-json
可以实现:
import perfectJson from 'perfect-json';
const obj =
Repeat:
Name: [['Top_level', 'All'], [[1, 1]]],
Link: [['Top_level'], [[1, 1]]]
,
Delete: ['Confirm', 'Cancel'],
Move: ['Up', 'Down'],
Number: ['Ascending', 'Descending']
;
console.log(perfectJson(obj,
singleLine: ( key, path, depth ) =>
if (['Delete', 'Move'].includes(key))
return true;
if (depth >= 3 && ['Name', 'Link'].includes(path[1]))
return true;
return false;
));
按照问题中的要求,将每个数组放在一行上也很容易:
console.log(perfectJson(obj,
indent: 4,
singleLine: ( value ) => Array.isArray(value)
));
【讨论】:
正好赶上这个问题的十周年。给我时间吸收它;我相信它值得一票。以上是关于Json - 字符串化,使数组在一行上的主要内容,如果未能解决你的问题,请参考以下文章
如何在node.js“html页面”中显示json字符串化数组数据?