【问题标题】:javascript array tree search keep the node and parentsjavascript数组树搜索保留节点和父母
【发布时间】:2018-06-25 13:27:06
【问题描述】:

尝试实现一个采用数组(树结构)和字符串关键字的树搜索函数,将返回一个树数组,但只保留匹配的节点及其父节点。

function search(nodes, keyword){

}



const nodes = [
  {
    value: "1-1",
    children: [
      { value: "1-1-1"},
      { value: "1-1-2", children:[
        {
          value: "1-1-2-1",
          children: [
            { value: "1-1-2-1-1" },
            { value: "1-1-2-1-2" }
          ]
        },
        {
          value: "1-1-2-2"
        }
      ] }
    ]
  },
  {
    value: "1-2",
    children: [
      { value: "1-2-1"},
      { value: "1-2-2", children:[
        {
          value: "1-2-2-1",
          children: [
            { value: "1-2-2-1-1" },
            { value: "1-2-2-1-2" }
          ]
        },
        {
          value: "1-2-2-2"
        }
      ] }
    ]
  },
];

预期输出将是一棵树,其节点值包含“1-1-2-1”,其父节点如下

const searchedNodes = search(nodes, "1-1-2-1"); 



[
    {
    value: "1-1",
    children: [
      { value: "1-1-2", children:[
        {
          value: "1-1-2-1",
          children: [
            { value: "1-1-2-1-1" }
          ]
        }
      ] }
    ]
  }
]
*/

2018-06-26 更新

我做了一个工作的(DFS),但可能效率不高。

const search = (nodes, keyword) => {
    let newNodes = [];
    for (let n of nodes) {
      if (n.children) {
        const nextNodes = this.keywordFilter(n.children, keyword);
        if (nextNodes.length > 0) {
          n.children = nextNodes;
        } else if (n.label.toLowerCase().includes(keyword.toLowerCase())) {
          n.children = nextNodes.length > 0 ? nextNodes : [];
        }
        if (
          nextNodes.length > 0 ||
          n.label.toLowerCase().includes(keyword.toLowerCase())
        ) {

          newNodes.push(n);
        }
      } else {
        if (n.label.toLowerCase().includes(keyword.toLowerCase())) {
          newNodes.push(n);
        }
      }
    }
    return newNodes;
  };

【问题讨论】:

  • 什么符合'1-1-2-1-1' 而不是'1-1-2-1-2'?顺便说一句,你试过什么?

标签: javascript search tree treeview


【解决方案1】:

你需要迭代相同级别的节点并检查值是否相等,然后取该节点并退出循环。否则检查孩子并生成一个新对象以防止改变原始数据。

function search(nodes, value) {
    var result;

    nodes.some(o => {
        var children;
        if (o.value === value) {
            return result = o;
        }
        if (o.children && (children = search(o.children, value))) {
            return result = Object.assign({}, o, { children });
        }
    });

    return result && [result];
}


const nodes = [{ value: "1-1", children: [{ value: "1-1-1" }, { value: "1-1-2", children: [{ value: "1-1-2-1", children: [{ value: "1-1-2-1-1" }, { value: "1-1-2-1-2" }] }, { value: "1-1-2-2" }] }] }, { value: "1-2", children: [{ value: "1-2-1" }, { value: "1-2-2", children: [{ value: "1-2-2-1", children: [{ value: "1-2-2-1-1" }, { value: "1-2-2-1-2" }] }, { value: "1-2-2-2" }] }] }];

console.log(search(nodes, "1-1-2-1"));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 只有最后一个孩子是数组。因此这不是正确的解决方案
  • @SatheeshNatarajan。它返回想要的节点(包括所有子节点)和父节点。它出了什么问题?
  • 查看输入数据,其中属性“children”是所有嵌套对象的数组。但是你的代码的输出,所有的孩子都是对象而不是数组(除了最后一个孩子)。
  • @SatheeshNatarajan,对不起,你是对的。请参阅编辑。
  • 是否可以从整个数组中搜索匹配项?
猜你喜欢
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 1970-01-01
  • 2021-06-11
相关资源
最近更新 更多