将深层对象映射到新对象的更好方法

时间:2019-04-11 15:03:00

标签: javascript node.js json recursion mapping

此代码用于将JSON转换为一个对象,其中每个名称对象都将变成其值的键,或者如果它具有自己的元素对象则将其分解并对其内容执行相同的操作。

是否有更好的方法可以实现JSON模式的扩展性?
是否有办法将所有内容简化为一个更简单的函数,即可以传递第一个元素并将其转换为架构所经过的任何深度?

const fs = require('fs');
{
    let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version='1.0'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
    let depth = 0;

    var compiled = {
        [scheme.ele.name]: scheme.ele.ele.map(function(i) {
            if (typeof i.ele != 'undefined') {
                return {
                    [i.name]: i.ele.map(function(k) {
                        if (typeof k.ele != 'undefined') {
                            return {
                                [k.name]: k.ele.map(function(p) {
                                    if (typeof p.ele != 'undefined') {
                                        return {
                                            [p.name]: p.ele
                                        };
                                    } else {
                                        return {
                                            [p.name]: p.value
                                        };
                                    }
                                })
                            };
                        } else {
                            return {
                                [k.name]: k.value
                            };
                        }
                    })
                };
            } else {
                return {
                    [i.name]: i.value
                };
            }
        })
    };
}

console.log(JSON.stringify(compiled, 0, 2));

我应该补充一点,这旨在最终还应用验证并在到达字符串对象时获取真实数据。

输出看起来像这样:

{
    "REPORT": [
    {
        "SEGMENT0": [
        {
            "NUMBER1": ""
        },
        {
            "NUMBER2": ""
        }
        ]
    },
    {
        "SEGMENT1": [
        {
            "RECORD1": [
            {
                "NUMBER1": ""
            },
            {
                "NUMBER2": ""
            }
            ]
        }
        ]
    },
    {
        "SEGMENT2": []
    },
    {
        "SEGMENT3": []
    },
    {
        "SEGMENT4": []
    },
    {
        "SEGMENT5": []
    }
    ]
}

2 个答案:

答案 0 :(得分:5)

您可以分解对象,获取nameelevalue并以name作为键返回一个新对象,并通过映射{的对象来返回一个数组{1}}或ele

value
const
    getData = ({ name, ele, value }) => ({
        [name]: Array.isArray(ele)
            ? ele.map(getData)
            : value
    });

var scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0\'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root,
    result = getData(scheme.ele);

console.log(result);

答案 1 :(得分:1)

Nina的答案更简洁,但这看起来更像您的代码,所以我认为我还是会发布它。

let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":"1"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"2"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let newScheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":"1"},{"name":"NUMBER2","value":"3"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"4"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;

//Yay, recursion!
function mapObj(a, o = {}) {

  let array = o[a.name] || [];

  for (let i = 0; i < a.ele.length; i++) {

    let b = a.ele[i];
    array[i] = b.ele ?
      mapObj(b, array[i]) : {
        [b.name]: b.value
      };
  }
  
  o[a.name] = array;
  return o;

}

let obj = mapObj(scheme.ele);

console.log(obj);
console.log(mapObj(newScheme.ele, obj));

相关问题