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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM