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


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

## input
```js
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

見やすく整形済み。

```html
<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のフォーマットを利用して整形されたテキストをひたすら置換する。

```js
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;
}

```

## 改良版
https://github.com/mafumafuultu/obj2tbl