【问题标题】:How to convert a tree into an array?如何将树转换为数组?
【发布时间】:2019-09-12 09:24:52
【问题描述】:

我有一个树对象,它是一棵不规则的树,每次我运行我的代码时,孩子的名字和键值都会改变。例如:

{
    addressRouter: 192.168.0.1,   
    addresses: 
        {
            address1: 'A',   

        },
        {
            address2: 'B',   

        },
        {
            ports: [
                {
                    portA: 'C',   
                    portB: null
                },


        }
    route: 'D',

}

所以名称:'addressRouter'、'addresses'、'address1'等及其键是不可预测的,但我需要将树对象转换为具有以下格式的数组:

addressRouter
addresses/address1
addresses/address2
addresses/ports/portA
addresses/ports/portB
route

然后把他们的钥匙放在他们旁边。

我有这个函数来构造树,这是正确的:

const iterate = (obj, obj2) => {
  Object.keys(obj).forEach(key => {

    obj2[key] = obj[key];

    if (typeof obj[key] === 'object') {
        iterate(obj[key], obj2)
    }
  })
}

但调试后,我意识到它并没有得到所有的分支。

【问题讨论】:

  • 您能否向我们展示实际的示例数组,您希望它们最终以 JSON 表示法如何?我没有从你的“格式”描述中得到你想要的输出,是否应该有嵌套数组忽略键名或其他东西?
  • @JeyDWork 我想将第一个灰色框中显示的对象转换为第二个灰色框中显示的字符串。我刚刚意识到我的迭代函数并没有涵盖所有分支,所以我认为我需要纠正它
  • 所以数组应该是 ["addressRouter", "addresses/address1", "addresses/address2", "addresses/ports/portA", "addresses/ports/portB", "route"] 完全一样,忽略原始对象中的值,键以 / 作为分隔符连接在一起?
  • @JeyDWork 是的!确切地! :)
  • @JeyDWork 只是找到一个可能的解决方案并将其写为答案

标签: arrays node.js list tree


【解决方案1】:

我们可以使用递归函数来遍历树并获取所需格式的键。

我假设给定树对象中的地址是一个对象数组

function processTree(obj, rootKey) {
    const arr = [];
    obj && Object.keys(obj).forEach(key => {
        const val = obj[key];  
        if (val && val instanceof Array) {
            val.forEach(item => arr.push(...processTree(item, key)))
        }else if (val && typeof(val) == "object") {
            arr.push(...processTree(val, key));
        }else {
            arr.push(key);
        }
    });
    return rootKey ? arr.map(item => rootKey + "/" + item) : arr;
}

console.log(processTree(tree, null));

结果:["addressRouter", "addresses/address1", "addresses/address2", "addresses/ports/portA", "addresses/ports/portB", "route"]

【讨论】:

    【解决方案2】:

    我只是在下面写代码,看看是不是你想要的。

    const tree = {
      addressRouter: '192.168.0.1',
      addresses: [
        {
          address1: 'A',
        },
        {
          address2: 'B',
        },
        {
          ports: [
            {
              portA: 'C',
              portB: null,
            },
          ],
        },
      ],
      route: 'D',
    };
    const traverse = (input) => {
      const resultList = [];
      const isEndPoint = (obj) => {
        return typeof obj !== 'object' || obj === null;
      };
      const buildPath = (currentPath, key) =>
        currentPath === '' ? key : `${currentPath}/${key}`;
      const innerTraverse = (tree, currentPath = '') => {
        if (tree !== null && typeof tree === 'object') {
          Object.entries(tree).forEach(([key, value]) => {
            if (isEndPoint(value)) {
              resultList.push(buildPath(currentPath, key));
              return;
            }
            let path = currentPath;
            if (!Array.isArray(tree)) {
              path = buildPath(currentPath, key);
            }
            innerTraverse(value, path);
          });
        }
      };
      innerTraverse(input);
      return resultList;
    };
    
    console.log(traverse(tree));
    /**
     * [
     * 'addressRouter',
     * 'addresses/address1',
     * 'addresses/address2',
     * 'addresses/ports/portA',
     * 'addresses/ports/portB',
     * 'route'
     * ]
     */

    【讨论】:

      【解决方案3】:

      我刚刚找到了我需要的循环here,即:

      function* traverse(o,path=[]) {
      
          for (var i of Object.keys(o)) {
      
              const itemPath = path.concat(i);
              yield [i,o[i],itemPath];
      
              if (o[i] !== null && typeof(o[i])=="object") {
      
                  //going one step down in the object tree!!
      
                  yield* traverse(o[i],itemPath);
              }
          }
      }
      

      然后,如果树对象(我的问题中的第一个灰色框)是名称,例如“params”,我会这样做:

      if (params != null && params != undefined) {
          for(var [key, value, path] of traverse(params)) {
            // do something here with each key and value
      
              if (typeof value == 'string'){
      
                  var tempName = '';
                  for (name in path) {
      
                      //console.log(path[name])
      
                      p= tempName += path[name] + "/" 
      
                  }
              console.log(p, value)
      
              }
            }
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-09
        • 2019-10-29
        • 1970-01-01
        • 2011-05-18
        • 2013-03-25
        • 1970-01-01
        相关资源
        最近更新 更多