连接每个节点的树路径

时间:2018-11-18 04:26:56

标签: javascript node.js

这应该很容易,但是我的脑子屁,我的结构像这样:

  interface EntitiesMap {
    name: string, 
    children: Array<EntitiesMap>,
  }

树没有循环。这样看起来像:

const m = {
   name: 'foo',
   children: [{
     name: 'Baz1',
     children: [ ...etc ]
     }, {
      name:'Bar',
      children:[]
   }]
}

对于树中的每个节点,我只是想加入名称字段。 例如,如果我有这棵树:

foo ----- Baz1 ---- Baz2 ------Baz5
 \          \           \
   Bar       \           \
              Baz3       Baz4

因此对于foo(根)节点,我将具有以下名称列表:

FooBar
FooBaz1Baz2Baz5
FooBaz1Baz3
FooBaz1Baz2Baz4

由于树有4个技巧,所以根(foo)节点有4条路径。

对于Baz1节点,我们有3个提示:

Baz1Baz2Baz5
Baz1Baz2Baz4
Baz1Baz3

必须基于EntitiesMap树结构,有一种简单的方法来生成这些字符串,但我确实为此感到困惑。我正在寻找一种不太聪明的好的算法/简单算法。

3 个答案:

答案 0 :(得分:1)

您可以递归地执行此操作-获取每个孩子的名字,并将“此”节点的名字与每个孩子的每个结果串联起来:

function joinNames(node) {
  if (node.children.length === 0) return [node.name];
  let names = [];
  node.children.forEach(n =>
    joinNames(n).forEach(cn =>
      names.push(node.name + cn)));
  return names;
}

const m = {
  name: 'Foo',
  children: [{
      name: 'Baz1',
      children: [{
          name: 'Baz3',
          children: []
        },
        {
          name: 'Baz2',
          children: [{
              name: 'Baz4',
              children: []
            },
            {
              name: 'Baz5',
              children: []
            }
          ]
        }
      ]
    },
    {
      name: 'Bar',
      children: []
    }
  ]
};


console.log(joinNames(m));
console.log(joinNames(m.children[0])); // 'Baz1' as root

答案 1 :(得分:1)

让我们在这里进行一些功能编程!

let allPaths = node => node.children
    ? node.children.flatMap(c => allPaths(c)).map(p => [node.name].concat(p))
    : [node.name]

//

tree = {
    name: 1,
    children: [
        {name: 2, children: [{name: 3}, {name: 4}]},
        {name: 5, children: [{name: 6, children: [{name: 7}]}]},
    ]
}

console.log(JSON.stringify(allPaths(tree)))

如果您的平台不支持flatMap,则polyfill可能类似于

Array.prototype.flatMap = function (fn) {
    return [].concat(...this.map(fn))
}

答案 2 :(得分:1)

有时将当前路径作为参数传递给递归函数可以简化函数并使事情更容易理解。这是一种可行的方法:

const m = {name: 'foo',children: [{name: 'Baz1',children: [ {name: "Baz3",children: []},{name: "Baz2",children: [{name: "Baz5",children: []},{name: "Baz4",children: []}]}]}, {name:'Bar',children:[]}]}

function getPath(node, path=""){
  return (node.children.length == 0) 
    ? [path + node.name]
    : node.children.reduce((arr, child) => 
        arr.concat(...getPath(child, path + node.name)), [])
    
}
console.log(getPath(m))