如何将树结构展平为数组数组

时间:2018-01-30 14:42:26

标签: javascript arrays combinations

给出这样的结构:

setInterval(function() {
   $.ajax({
     type: 'GET',
     url: "https://www.example.com/ajax.php",
     data :"ch="+count,
      success: function(result){
         $("#text").html(result);
     }});
 }, 30000);

也就是说:

  1. 它只有var node = { children: [] } 属性。
  2. 没有children财产。
  3. 没有parent财产。
  4. 如何使用自上而下的方法构建包含所有叶节点路径的数组的平面列表:

    1. 该算法不使用任何辅助方法,只使用纯JavaScript。
    2. 算法在从顶部遍历树时构建数组。
    3. 所以这是一个示例数据:

      nextSibling

      该函数应返回:

      var node = {
        item: 1,
        children: [
          {
            item: 2,
            children: [
              {
                item: 3,
                children: [
                  {
                    item: 4,
                    children: []
                  },
                  {
                    item: 5,
                    children: []
                  },
                  {
                    item: 6,
                    children: [
                      {
                        item: 7,
                        children: []
                      },
                      {
                        item: 8,
                        children: []
                      },
                      {
                        item: 9,
                        children: []
                      }
                    ]
                  }
                ]
              },
              {
                item: 10,
                children: [
                  {
                    item: 11,
                    children: []
                  },
                  {
                    item: 12,
                    children: [
                      {
                        item: 13,
                        children: []
                      },
                      {
                        item: 14,
                        children: []
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
      

      到目前为止,我的尝试是:

      [
        [1, 2, 3, 4],
        [1, 2, 3, 5],
        [1, 2, 3, 6, 7],
        [1, 2, 3, 6, 8],
        [1, 2, 3, 6, 9],
        [1, 2, 10, 11],
        [1, 2, 10, 12, 13],
        [1, 2, 10, 12, 14]
      ]
      

4 个答案:

答案 0 :(得分:2)

递归方法是:

csv_input = pd.read_csv(fn, error_bad_lines=False)
if csv_input['ip.src'] == '192.168.1.100':
        csv_input['flow_dir'] = 1  
        csv_input['ip.src'] = 1  
        csv_input['ip.dst'] = 0
    else:
        if csv_input['ip.dst'] == '192.168.1.100':
            csv_input['flow_dir'] = 0  
            csv_input['ip.src'] = 0
            csv_input['ip.dst'] = 1  

或者一些hacky ES6:

 function traverse(node, path = [], result = []){
     if(!node.children.length)
        result.push(path.concat(node.item));
     for(const child of node.children)
         traverse(child, path.concat(node.item), result);
     return result;
 }

现在调用const traverse = node => (node.children.length?[]:[[node.item]]).concat(...node.children.map(child => traverse(child).map(arr => [node.item].concat(arr) ) )); 将返回所需的结果。

答案 1 :(得分:1)

不大喜欢重新发明轮子。因此,这里是使用object-scan的解决方案。一旦将头缠住它,它就是用于数据处理的强大工具。

根据您需要的顺序,您也许可以摆脱最后一个reverse()

const objectScan = require('object-scan');

const find = (tree) => objectScan(['**.children'], {
  filterFn: ({ value, parents, context }) => {
    if (value.length === 0) {
      context.push(
        parents
          .filter((p) => 'item' in p)
          .map(({ item }) => item)
          .reverse()
      );
    }
  }
})(tree, []).reverse();

const node = {"item":1,"children":[{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]}]};

console.log(find(node));
// => [ [ 1, 2, 3, 4 ],
//   [ 1, 2, 3, 5 ],
//   [ 1, 2, 3, 6, 7 ],
//   [ 1, 2, 3, 6, 8 ],
//   [ 1, 2, 3, 6, 9 ],
//   [ 1, 2, 10, 11 ],
//   [ 1, 2, 10, 12, 13 ],
//   [ 1, 2, 10, 12, 14 ] ]

编辑:如果性能很重要,这是一个更有效的解决方案

const objectScan = require('object-scan');

const find = (tree) => objectScan(['**.children'], {
  breakFn: ({ isMatch, parent, context: { stack } }) => {
    if (isMatch) {
      stack.push(parent.item);
    }
  },
  filterFn: ({ value: { length }, context: { result, stack } }) => {
    if (length === 0) {
      result.push([...stack]);
    }
    stack.pop();
  }
})(tree, { stack: [], result: [] }).result.reverse();

const node = {"item":1,"children":[{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]}]};

console.log(find(node));
// => [ [ 1, 2, 3, 4 ],
//   [ 1, 2, 3, 5 ],
//   [ 1, 2, 3, 6, 7 ],
//   [ 1, 2, 3, 6, 8 ],
//   [ 1, 2, 3, 6, 9 ],
//   [ 1, 2, 10, 11 ],
//   [ 1, 2, 10, 12, 13 ],
//   [ 1, 2, 10, 12, 14 ] ]

答案 2 :(得分:0)

您可以使用函数查找子节点或返回最后一个节点的路径来进行迭代和递归方法。



function flatNodes(node) {
    const iter = temp => ({ item, children = [] }) => children.length
            ? children.forEach(iter(temp.concat(item)))
            : nodes.push(temp.concat(item));

    var nodes = [];
    [node].forEach(iter([]));
    return nodes;
}

var node = { item: 1, children: [{ item: 2, children: [{ item: 3, children: [{ item: 4, children: [] }, { item: 5, children: [] }, { item: 6, children: [{ item: 7, children: [] }, { item: 8, children: [] }, { item: 9, children: [] }] }] }, { item: 10, children: [{ item: 11, children: [] }, { item: 12, children: [{ item: 13, children: [] }, { item: 14, children: [] }] }] }] }] };

console.log(flatNodes(node).map(a => JSON.stringify(a)));

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 3 :(得分:0)

您可以创建递归函数,并首先检查当前元素是否为数组或对象,并将先前的项目编号存储在一个变量中。

var node = {"item":1,"children":[{"item":2,"children":[{"item":3,"children":[{"item":4,"children":[]},{"item":5,"children":[]},{"item":6,"children":[{"item":7,"children":[]},{"item":8,"children":[]},{"item":9,"children":[]}]}]},{"item":10,"children":[{"item":11,"children":[]},{"item":12,"children":[{"item":13,"children":[]},{"item":14,"children":[]}]}]}]}]}

const result = []
function flat(data, prev = '') {
  if (Array.isArray(data)) {
    data.forEach(e => flat(e, prev))
  } else {
    prev = prev + (prev.length ? '.' : '') + data.item;
    if (!data.children.length) result.push(prev.split('.').map(Number))
    else flat(data.children, prev)
  }
}

flat(node)
console.log(result)