为什么要平坦化
在使用有Vue能力的html table时,需要用到对象数组,Vue内部用对象的字段获取对应值,而如果对象层次较深可能就难以直接使用字段。下面是一个简单的例子:
<el-table :data="table_data">
<el-table-column prop="field_1" label="字段1"></el-table-column>
<el-table-column prop="field_2" label="字段2"></el-table-column>
</el-table>
const app = {
data() {
return {
table_data: [
{"field_1": 111},
{"field_2": 112}
]
};
}
};
如果数据层次深一些,有可能UI组件无法处理,如下例所示:
[
{"field_1": {"name":111}},
{"field_2": {"name":112}}
]
[
{"field_1": [111,true]},
{"field_2": [112,false]}
]
可见Table的绑定数据最好是扁平的JSON数据,此时需要平坦化解决该问题。
编码
function flat(obj, prefix, is_arr) {
if (!prefix) {
prefix = "";
is_arr = false;
var tobj = Object.prototype.toString.call(obj);
if (tobj == "[object Array]") {
is_arr = true;
}
}
return Object.keys(obj).reduce(function(memo, prop) {
var tobj = Object.prototype.toString.call(obj[prop]);
var ppre = prefix ? prefix + '.' : "";
var sub_prefix = is_arr ? prefix + '[' + prop + ']' : ppre + prop;
if (tobj === "[object Object]") {
return Object.assign({}, memo, flat(obj[prop], sub_prefix, false));
} else if (tobj === "[object Array]") {
return Object.assign({}, memo, flat(obj[prop], sub_prefix, true));
} else {
return Object.assign({}, memo, {[sub_prefix]: obj[prop]});
}
}, {});
}
测试发现ch:
{
"a0": {
"b00": "c00",
"b01": "c01",
},
"a1": [
"b10", "b11"
],
"a2":{
"b20":[{
"c3":{
"d3":"ok"
}
}],
"b21":[{
"c3":{
"d3":"ok"
}
},
"b22"],
}
}
{
"a0.b00": "c00",
"a0.b01": "c01",
"a1[0]": "b10",
"a1[1]": "b11",
"a2.b20[0].c3.d3": "ok",
"a2.b21[0].c3.d3": "ok",
"a2.b21[1]": "b22"
}