【问题标题】:how to find object using recursion in javascript?如何在javascript中使用递归查找对象?
【发布时间】:2020-04-02 12:32:14
【问题描述】:
let tree = {
    name: "A",
    children: [
        {
            name: 'A-1',
            children: [
                {name: "A-1-A"},
                {name: "A-1-B"},
            ]
        },
        {
            name: 'B-1',
            children: [
                {
                    name: "B-1-A",
                    children: [
                        {name: "B-11-A"},
                        {name: "B-11-B"}
                    ]
                },
                {name: "B-1-B"},
            ]
        },

    ]


};

我正在尝试使用递归从tree object 中找到object

当我这样调用 searchFn(tree,'A-1') 时,它应该返回 { name: 'A-1', children: [ {name: "A-1-A"}, {name: "A-1-B"}, ] } 对象

我这样称呼searchFn(tree,'A-1-A') 它应该返回这个

{name: "A-1-A"}

我试过这样但没有用

 function searchFn(obj ,searchText){
        if(obj.name === searchText) return obj
        if(obj.children.length > 0){
          return   searchFn(obj.children.pop(),searchText)
        }
      return null
    }

【问题讨论】:

    标签: javascript recursion tree


    【解决方案1】:

    您需要迭代对象的子对象并为结果取一个变量。

    function searchFn(object, searchText) {
        var result;
        if (object.name === searchText) return object;
        (object.children || []).some(o => result = searchFn(o, searchText));
        return result || null;
    }
    
    
    let tree = { name: "A", children: [{ name: 'A-1', children: [{ name: "A-1-A" }, { name: "A-1-B" }] }, { name: 'B-1', children: [{ name: "B-1-A", children: [{ name: "B-11-A" }, { name: "B-11-B" }] }, { name: "B-1-B" }] }] };
    
    console.log(searchFn(tree, 'foo'));
    console.log(searchFn(tree, 'A-1'));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      首先,您应该为可读性创建一个类。然后,您应该在函数内部有一个循环,该循环遍历子级并且仅在找到子级时才返回。

          class Node {
              static fromStruct = (struct) => {
                  const tree = new Node(struct.name);
                  if(!struct.children) return tree;
                  for(const child of struct.children) {
                      tree.children.push(Node.fromStruct(child));
                  }
                  return tree;
              }
      
              constructor(name){
                  this.name = name;
                  this.children = [];
              }
          
              addChild = (parentName, childName) => {
                  const parent = this.searchFn(parentName);
                  if(!parent) throw new Error("Parent not found");
                  parent.children.push(new Node(childName));
              }
          
              searchFn = (name) => {
                  if(this.name === name) return this;
                  for(const child of this.children) {
                      const found = child.searchFn(name);
                      if(found !== null) return found;
                  }
                  return null;
              }
          }
      
      
          const data = {
              name: "A",
              children: [
                  {
                      name: 'A-1',
                      children: [
                          {name: "A-1-A"},
                          {name: "A-1-B"},
                      ]
                  },
                  {
                      name: 'B-1',
                      children: [
                          {
                              name: "B-1-A",
                              children: [
                                  {name: "B-11-A"},
                                  {name: "B-11-B"}
                              ]
                          },
                          {name: "B-1-B"},
                      ]
                  },
          
              ]
          };
      
          const tree = Node.fromStruct(data);
          console.log(tree.searchFn("A-1-A"));

      【讨论】:

      • 你能用样本运行吗
      • @user944513 我改进了很多
      【解决方案3】:

      const tree = {"name":"A","children":[{"name":"A-1","children":[{"name":"A-1-A"},{"name":"A-1-B"}]},{"name":"B-1","children":[{"name":"B-1-A","children":[{"name":"B-11-A"},{"name":"B-11-B"}]},{"name":"B-1-B"}]}]}
      
      const searchFn = (tree, name) => {
        let result = null;
        if (typeof tree !== "object") return result;
        if (tree.name === name) return tree;
        if (tree.children && tree.children.length) {
          tree.children.some(data => (result = searchFn(data, name)));
        }
        return result;
      };
      console.log(searchFn(tree, "A-1-A"));
      console.log(searchFn(tree, "A-1"));
      console.log(searchFn(tree, ""));
      .as-console-row {color: blue!important}

      【讨论】:

        【解决方案4】:

        你可以试试这样的

        let tree = { name: "A", children: [{ name: 'A-1', children: [{ name: "A-1-A" }, { name: "A-1-B" }] }, { name: 'B-1', children: [{ name: "B-1-A", children: [{ name: "B-11-A" }, { name: "B-11-B" }] }, { name: "B-1-B" }] }] };
        
        function searchFn(obj, text){
          if(obj.name === text) return obj
          else{
            if(obj && obj.children && Array.isArray(obj.children)){
              for(let value of obj.children){
                if(searchFn(value, text)){
                  return searchFn(value, text)
                }
              }
            }
          }
          return null
        }
        
        console.log(searchFn(tree, 'A-1'))
        console.log(searchFn(tree, 'A-1-A'))
        console.log(searchFn(tree, 'A-A-A'))

        【讨论】:

          【解决方案5】:

          您的函数的问题在于,它只检查传递对象的children 属性中的数组中弹出的元素,而不检查其他元素。试试这个:

          function searchFn(obj ,searchText) { 
              if(obj.name === searchText) return obj; 
              if(obj.children) {
                  for (let x of obj.children) {
                      let y = searchFn(x,searchText);
                      if (y)
                          return y;
                  }
              }
              return null; 
          }
          

          【讨论】:

            猜你喜欢
            • 2019-04-22
            • 2016-08-07
            • 2015-06-10
            • 2019-01-31
            • 2017-08-02
            • 1970-01-01
            • 2016-10-24
            • 1970-01-01
            • 2018-12-19
            相关资源
            最近更新 更多