【问题标题】:Create a JSON object using an array of nodes使用节点数组创建 JSON 对象
【发布时间】:2019-03-07 19:33:59
【问题描述】:

我是一个表的结果,它为我提供了我需要用来创建 JSON 对象的字段的动态层次结构。

前:

[ [ '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}}}

任何帮助将不胜感激。

【问题讨论】:

    标签: node.js json


    【解决方案1】:

    因为obj 引用了final,所以这行很可能会引起你的恶作剧:

            obj = obj[key];
    

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

    【讨论】:

    • 我认为是这种情况,但我需要将循环的先前结果传递到新循环中才能正确变异。或者找到某种方法将所有结果合并到最终对象中。
    【解决方案2】:

    我有这个解决方案,但我认为还有很大的简化和改进空间,我也将 null 替换为 {}。

    您可以使用 _.set from lodash: 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);

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-28
        • 2018-07-03
        • 2013-12-25
        • 2014-09-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多