JavaScript实现JSON排序与格式化
因为公司内网没办法用BEJSON这些网站,于是网上找了一些代码缝合出这么一个东西
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Document</title>
</head>
<style>
body {
width: 1320px;
}
div {
display: inline;
}
textarea {
width: 600px;
height: 700px;
font-family: "Fira Code";
font-size: 14px;
}
</style>
<body>
<div id="in" style="float: left;">
<span>原JSON串</span>
<br>
<textarea id="in_area"></textarea>
</div>
<div id="out" style="float: right;">
<span>排序后结果(<span id="sort_type"></span>)</span>
<br>
<textarea id="out_area"></textarea>
</div>
<br/>
<div id="button" style="position: relative; left: 100px;">
<input
value="正序"
type="button"
onclick="doSort(this,1)"
style="
background-color: blue;
color: white;
width: 160px;
height: 100px;
"
/>
<input
value="反序"
type="button"
onclick="doSort(this,2)"
style="
background-color: red;
color: white;
width: 160px;
height: 100px;
margin-left: 100px;
"
/>
<br/>
</div>
</body>
<script>
function doSort(ele, type) {
document.getElementById("sort_type").innerHTML = ele.value;
document.getElementById("out_area").style.borderColor = ele.style.backgroundColor;
document.getElementById("out_area").style.borderWidth = "3px";
let text = document.getElementById("in_area").value;
let obj;
try {
obj = JSON.parse(text);
} catch (e) {
document.getElementById("out_area").innerText = e;
}
let newJSON = sortJSON(obj, type);
document.getElementById("out_area").innerText = formatJson(newJSON);
}
/**
* old 对象
* sortType 排序方式 1正序 2反序
*/
function sortJSON(old, sortType) {
let type = Object.prototype.toString.call(old);
let res = {};
// 如果是对象就对key排序,生成一个新的对象返回
if ("[object Object]" === type) {
let keyArray = [];
for (let key in old) {
keyArray.push(key);
}
keyArray.sort();
1 != sortType && keyArray.reverse();
for (let key in keyArray) {
key = keyArray[key];
let value = old[key];
res[key] = sortJSON(value, sortType);
}
return res;
}
if ("[object Array]" === type) {
let type = Object.prototype.toString.call(old[0]);
// 如果数组里嵌套字符串和数字,直接对数组排序
if ("[object String]" === type || "[object Number]" === type) {
old.sort();
1 != sortType && old.reverse();
return old;
}
// 如果数组里嵌套对象,不改变对象顺序,只改变对象内属性顺序
let newArray = [];
for (let i = 0; i < old.length; i++) {
newArray.push(sortJSON(old[i], sortType));
}
return newArray;
}
// 对对象里的value排序,但不是对象活数组,就原样返回
return old;
}
function formatJson(jsonObj) {
// 正则表达式匹配规则变量
var reg = null;
// 转换后的字符串变量
var formatted = '';
// 换行缩进位数
var pad = 0;
// 一个tab对应空格位数
var PADDING = ' ';
// json对象转换为字符串变量
var jsonString = JSON.stringify(jsonObj);
// 存储需要特殊处理的字符串段
var _index = [];
// 存储需要特殊处理的“再数组中的开始位置变量索引
var _indexStart = null;
// 存储需要特殊处理的“再数组中的结束位置变量索引
var _indexEnd = null;
// 将jsonString字符串内容通过\r\n符分割成数组
var jsonArray = [];
// 正则匹配到{,}符号则在两边添加回车换行
jsonString = jsonString.replace(/([\{\}])/g, '\r\n$1\r\n');
// 正则匹配到[,]符号则在两边添加回车换行
jsonString = jsonString.replace(/([\[\]])/g, '\r\n$1\r\n');
// 正则匹配到,符号则在两边添加回车换行
jsonString = jsonString.replace(/(\,)/g, '$1\r\n');
// 正则匹配到要超过一行的换行需要改为一行
jsonString = jsonString.replace(/(\r\n\r\n)/g, '\r\n');
// 正则匹配到单独处于一行的,符号时需要去掉换行,将,置于同行
jsonString = jsonString.replace(/\r\n\,/g, ',');
// 特殊处理双引号中的内容
jsonArray = jsonString.split('\r\n');
jsonArray.forEach(function (node, index) {
// 获取当前字符串段中"的数量
var num = node.match(/\"/g) ? node.match(/\"/g).length : 0;
// 判断num是否为奇数来确定是否需要特殊处理
if (num % 2 && !_indexStart) {
_indexStart = index
}
if (num % 2 && _indexStart && _indexStart != index) {
_indexEnd = index
}
// 将需要特殊处理的字符串段的其实位置和结束位置信息存入,并对应重置开始时和结束变量
if (_indexStart && _indexEnd) {
_index.push({
start: _indexStart,
end: _indexEnd
})
_indexStart = null
_indexEnd = null
}
})
// 开始处理双引号中的内容,将多余的"去除
_index.reverse().forEach(function (item, index) {
var newArray = jsonArray.slice(item.start, item.end + 1)
jsonArray.splice(item.start, item.end + 1 - item.start, newArray.join(''))
})
// 奖处理后的数组通过\r\n连接符重组为字符串
jsonString = jsonArray.join('\r\n');
// 将匹配到:后为回车换行加大括号替换为冒号加大括号
jsonString = jsonString.replace(/\:\r\n\{/g, ':{');
// 将匹配到:后为回车换行加中括号替换为冒号加中括号
jsonString = jsonString.replace(/\:\r\n\[/g, ':[');
// 将上述转换后的字符串再次以\r\n分割成数组
jsonArray = jsonString.split('\r\n');
// 将转换完成的字符串根据PADDING值来组合成最终的形态
jsonArray.forEach(function (item, index) {
console.log(item)
var i = 0;
// 表示缩进的位数,以tab作为计数单位
var indent = 0;
// 表示缩进的位数,以空格作为计数单位
var padding = '';
if (item.match(/\{$/) || item.match(/\[$/)) {
// 匹配到以{和[结尾的时候indent加1
indent += 1
} else if (item.match(/\}$/) || item.match(/\]$/) || item.match(/\},$/) || item.match(/\],$/)) {
// 匹配到以}和]结尾的时候indent减1
if (pad !== 0) {
pad -= 1
}
} else {
indent = 0
}
for (i = 0; i < pad; i++) {
padding += PADDING
}
formatted += padding + item + '\r\n'
pad += indent
})
// 返回的数据需要去除两边的空格
return formatted.trim();
}
</script>
</html>