json对象平坦化

json对象平坦化

为什么要平坦化

  在使用有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]});
        }
    }, {});
}   

测试

{ 
    "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"
}