LoginSignup
1
1

More than 5 years have passed since last update.

JSのObjectを<table>に整形するjs

Last updated at Posted at 2016-12-23

ArrayとかNumberとかStringとかネストの深さとか考えなくても大丈夫(のはず)。

input

var id = 'foo';
var data  = {
    "key101":"v201",
    "key102":["a201","a202"],
    "key103":{
        "key201":"v301",
        "key202":["a301","a302"],
        "key203":{
            "key301":"v401",
            "key302":["a401","a402"],
            "key303":{
                "key401":"v501",
                "key402":["a501","a502"],
                "key403":{
                    "key501":"v601"
                }
            }
        }
    },
    "key104":{
        "key201":["a301","a302"]
    },
    "key105":{
        "key201":{
            "key301":"v401"
        }
    }
};


objToTbl(id, data);

output

見やすく整形済み。

<table id="foo">
    <tr><td>key101</td><td colspan="5">v201</td></tr>
    <tr><td>key102</td><td colspan="5">a201</td></tr>
    <tr><td></td><td colspan="5">a202</td></tr>
    <tr><td>key103</td><td>key201</td><td colspan="4">v301</td></tr>
    <tr><td></td><td>key202</td><td colspan="4">a301</td></tr>
    <tr><td colspan="2"></td><td colspan="4">a302</td></tr>
    <tr><td></td><td>key203</td><td>key301</td><td colspan="3">v401</td></tr>
    <tr><td colspan="2"></td><td>key302</td><td colspan="3">a401</td></tr>
    <tr><td colspan="3"></td><td colspan="3">a402</td></tr>
    <tr><td colspan="2"></td><td>key303</td><td>key401</td><td colspan="2">v501</td></tr>
    <tr><td colspan="3"></td><td>key402</td><td colspan="2">a501</td></tr>
    <tr><td colspan="4"></td><td colspan="2">a502</td></tr>
    <tr><td colspan="3"></td><td>key403</td><td>key501</td><td colspan="1">v601</td></tr>
    <tr><td>key104</td><td>key201</td><td colspan="4">a301</td></tr>
    <tr><td colspan="2"></td><td colspan="4">a302</td></tr>
    <tr><td>key105</td><td>key201</td><td>key301</td><td colspan="3">v401</td></tr>
</table>

処理

JSONのフォーマットを利用して整形されたテキストをひたすら置換する。

var data  = {"key101":"v201","key102":["a201","a202"],"key103":{"key201":"v301","key202":["a301","a302"],"key203":{"key301":"v401","key302":["a401","a402"],"key303":{"key401":"v501","key402":["a501","a502"],"key403":{"key501":"v601"}}}},"key104":{"key201":["a301","a302"]},"key105":{"key201":{"key301":"v401"}}};

var id = 'foo';


// id: テーブルのID、 data: Object
objToTbl(id, data);

/* table を返却する @public*/
function objToTbl(id, data){
    var reg = /(<td><\/td>){1,}/; // 前方の空td検出用
    var depth = check_depth(data) + 1, arr = refact(data), txt = '';
    arr.shift();
    arr.pop();

    for(var i = 0, l = arr.length; i < l; i++){
        var row = arr[i].replace(/: /g, '\t').replace(/$/, '</td></tr>').replace(/^\t/, '<tr><td>').replace(/\t/g, '</td><td>');
        var xx = $(row).find('td').length, len = depth - xx;

        // value & 後方空td連結
        var tmp = row.replace(/<td>(\w*<\/td>)<\/tr>$/, `<td colspan="${len}">$1</tr>`);
        var fcols = reg.exec(tmp), fcollen = (fcols === null) ? 0 : fcols[0].split(fcols[1]).length - 1;
        txt += tmp.replace(/(<td><\/td>){1,}/,`<td colspan="${fcollen}"></td>`);
    }
    return `<table id="${id}">${txt}</table>`;
}

/* オブジェクトの深さを探索する @private */
function check_depth(data) {
    var jsonArr = JSON.stringify(data, null, '\t').replace(/(^(\{|\[)|(\{|\[)$)/g, '').split(',\n');
    var jl = jsonArr.length, result = [];
    for(var i = 0; i < jl; i++) {
        jsonArr[i] = jsonArr[i].replace(/(\r|\n|\r\n)/g, '').replace(/\t{1,}(\}|\])/g, '$1');
        var d = jsonArr[i].replace(/(\n|^\t|\t$)/g, '').trim();
        //console.log(d);
        result.push(d.split('\t').length);
    }

    return (result.length) ? Math.max.apply(null, result) : 0 ;
}

/* オブジェクトを表示用に整形する @private */
function refact(data) {
    var txt = JSON.stringify(data, null, '\t').replace(/(^(\{|\[)|(\{|\[)$|(\{|\[|\t{1,}(\}|\]))|,|\}|(^\n|\n$))/g, '');
    var splited = txt.replace(/(:[ ]{0,}(\r\n|\r|\n)\t{1,})/g,': ').replace(/(\r\n|\r|\n){1,}/g, '\n').replace(/\"/g, '').split('\n');
    return splited;
}

改良版

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1