js递归如何生成该数据的预览json格式?

需求就是通过json生成json,简化后的格式如下,如何通过递归的方式生成这些数据表示的最终格式?求教

//这个是各个类型生成的默认值
const defaultVal = {
    string:"默认值",
    int:1,
    float:0.1,
    double:10.34,
    boolean:false,
    array:null
}
//这个是json待转化的
[
    {
        "type": "object",
        "propertyName": "user",
        "children": [
            {
                "type": "string",
                "propertyName": "name",
                "children": null
            },
            {
                "type": "int",
                "propertyName": "age",
                "children": null,
                
            },
            {
                "type": "array",
                "propertyName": "data",
                "children": [
                    {
                        "type": "object",
                        "name": "name",
                        "children": null
                    }
                ]
            }
        ]
    }
]
//上述转化结果为:
{
    name:'默认值',
    age:1,
    data:[{}]
}
阅读 1.3k
4 个回答
function toData(rule, defVal, init) {
    const copy = val => JSON.parse(JSON.stringify(val));
    const initial = init ?? copy(defVal[rule.type]);
    return rule.children ? rule.children.reduce((res, v) => {
      if(Array.isArray(res)) res.push(toData(v, defVal));
      else if({}.toString.call(res) == '[object Object]') toData(v, defVal, res[v.propertyName] = copy(defVal[v.type]))
      return res;
  }, initial) : initial;
}

toData(
  {
    "type": "object",
    "propertyName": "user",
    "children": [
      {
        "type": "string",
        "propertyName": "name",
        "children": null
      },
      {
        "type": "int",
        "propertyName": "age",
        "children": null,

      },
      {
        "type": "array",
        "propertyName": "data",
        "children": [
          {
            "type": "object",
            "name": "name",
            "children": null
          }
        ]
      }
    ]
  },
  {
    string:"默认值",
    int:1,
    float:0.1,
    double:10.34,
    boolean:false,
    array:[],
    object: {},
  }
)

根据判断数据类型,下面简单的判断力一下,针对float等再详细判断

let data = {
  name: "张三",
  age: 15,
  i: 19.8,
  score: [{ english: 89.5, chinese: 97.0 }],
};
let list = this.getData(data, []);
console.log(list)
getData(data, list) {
  let obj = {};
  for (let key in data) {
    obj = {
      type: typeof data[key],
      propertyName: key,
      children: null,
    };
    if (typeof data[key] !== "object") {
      // 不是对象和数组
      list.push(obj);
    } else {
      obj.children = [];
      if (data[key] instanceof Array) {
        data[key].forEach((item) => {
          obj.children = this.getData(item,obj.children);
        });
      }
      list.push(obj);
    }
  }
  return list
},
``
const parseJson = (json: any) => {
    if (Array.isArray(json)) {
        const result = [] as any;
        for (const item of json) {
            if (item.propertyType === 'object') {
                const obj = {} as any;
                if (item.children) {
                    for (const child of item.children) {
                        if (child.propertyName) {
                            obj[child.propertyName] = parseJson(child);
                        }
                    }
                }
                result.push(obj);
            } else if (item.propertyType === 'array') {
                const arr = parseJson(item.children);
                if (arr && arr.length > 0) {
                    result.push(arr);
                } else {
                    result.push(defaultVal[item.propertyType]);
                }
            } else {
                result.push(defaultVal[item.propertyType]);
            }
        }
        return result && result.length ? result : [];
    } else if (json.propertyType === 'object') {
        const obj = {} as any;
        for (const child of json.children) {
            if (child.propertyName) {
                obj[child.propertyName] = parseJson(child);
            }
        }
        return obj;
    } else if (json.propertyType === 'array') {
        return parseJson(json.children);
    } else {
        return defaultVal[json.propertyType];
    }
}

一种实现方式,试了下还可以,不知道有没有更好的方法

不及大佬们代码优雅,简单粗暴的实现了一下。

// 各类型默认值
const defaultVal = {
    string: "默认值",
    int: 1,
    float: 0.1,
    double: 10.34,
    boolean: false,
    array: null
}

// 转换前的 json
let users = [
    {
        "type": "object",
        "propertyName": "user",
        "children": [
            {
                "type": "string",
                "propertyName": "name",
                "children": null
            },
            {
                "type": "int",
                "propertyName": "age",
                "children": null,
                
            },
            {
                "type": "array",
                "propertyName": "data",
                "children": [
                    {
                        "type": "object",
                        "name": "name",
                        "children": null
                    }
                ]
            }
        ]
    }
]

// 准换结果:
//{
//    name:'默认值',
//    age:1,
//    data:[{}]
//}

// 遍历 users
function userJson(users){
    let res = [];
    for(u in users){
        res[u] = recurse(users[0].children);
    }
    if(res.length === 1) return res[0];
    return res;
}

// 递归方法
function recurse(jsonArray){
    let res = {};
    for(let p in jsonArray){
        let pType = jsonArray[p].type;
        let pName = jsonArray[p].propertyName || jsonArray[p].name;
        let pChild = jsonArray[p].children;
        if(pType === 'array'){
            res[pName] = recurseArr(pChild)
        }else{
            let pVal = defaultVal[pType];
            res[pName] = pVal;
        }
    }
    return res;
}

function recurseArr(jsonArray){
    let res = [];
    for(let p in jsonArray){
        let pType = jsonArray[p].type;
        let pName = jsonArray[p].propertyName || jsonArray[p].name;
        let pChild = jsonArray[p].children;
        res[p] = {}
        res[p][pName] = pChild !== null ? recurse(pChild) : {};
    }
    if(res.length === 1){
        if(res[0].name) res[0] = res[0].name;
    }
    return res;
}

// test
let res = userJson(users);
console.log(res); // { name: '默认值', age: 1, data: [ {} ] }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题