使用节点数组创建JSON对象

时间:2019-03-07 19:34:00

标签: node.js json

我得到一张表的结果,该表为我提供了用于创建JSON对象所需的字段的动态层次结构。

EX:

[ [ 'request', 'cycleRange' ],
  [ 'request', 'cycleRange', 'from' ],
  [ 'request', 'cycleRange', 'to' ],
  [ 'request', 'cycleRange', 'to', 'month' ],
  [ 'request', 'cycleRange', 'to', 'year' ],
  [ 'request', 'datestmt' ],
  [ 'request', 'singleTran' ],
  [ 'request', 'singleTran', 'datePost' ],
  [ 'request', 'singleTran', 'dateTo' ] ]

我希望通过此示例创建的JSON对象应为:

let expected = {
    request: {
        cycleRange: {
            from: null,
            to: {
                month: null,
                year: null
            }
        },
        datestmt: null,
        singleTran: {
            datePost: null,
            dateTo: null
        }
    }
};

我正在使用此函数尝试构建对象,但是我仅将最终数组作为对象:

let final = {};
for (let i of heirarchy) {
    assign(final, i, null);
}    

function assign(obj, keyPath, value) {
    let lastKeyIndex = keyPath.length - 1;
    let key;
    let i;

    for (i=0; i<lastKeyIndex; i++) {
        key = keyPath[i];

        if (!(key in obj)) {
            obj[key] = {};
        } else {
            if (i !== lastKeyIndex) {
                obj[key] = {};
            }
        }

        obj = obj[key];
    }

    obj[keyPath[lastKeyIndex]] = value;
}

当前我的结果仅是:(源层次结构的最后一个索引)

{"request":{"singleTran":{"dateTo":null}}}

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

由于obj引用了final,因此此行可能会导致您恶作剧:

        obj = obj[key];

这将在hte循环的每次迭代中覆盖obj(在本例中为final)。我建议您跟踪单独的变量,以使final保持不变

答案 1 :(得分:0)

我有此解决方案,但我认为有很多简化和改进的空间,我也用{}代替了null。

您可以使用lodash中的_.set:https://lodash.com/docs/4.17.11#set来替换示例中的set。

const array = [ [ 'request', 'cycleRange' ],
  [ 'request', 'cycleRange', 'from' ],
  [ 'request', 'cycleRange', 'to' ],
  [ 'request', 'cycleRange', 'to', 'month' ],
  [ 'request', 'cycleRange', 'to', 'year' ],
  [ 'request', 'datestmt' ],
  [ 'request', 'singleTran' ],
  [ 'request', 'singleTran', 'datePost' ],
  [ 'request', 'singleTran', 'dateTo' ] ];
  


const set = (path, obj) => path.split('.').reduce((o,i)=> {
     return o[i] ? o[i] : o[i] = {};
}, obj)

let myNewObject = {};
let path = '';

array.forEach(element => {
  path = '';
  element.forEach(key => {
     path = path ? path + '.' + key : key;
     set(path, myNewObject);
  });
});

console.log(myNewObject);

答案 2 :(得分:0)

我最终使用package deepmerge将单个结果合并到最终对象中

const deepmerge = require('deepmerge');
let final = {};
for (let i of heirarchy) {
    let temp = {};
    assign(temp, i, null);
    final = deepmerge(final, temp);
}