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"},
            ]
        },

    ]


};

Próbuję znaleźć object z tree object przy użyciu rekurencji.

Kiedy wywołuję w ten sposób searchFn(tree,'A-1'), powinno zwrócić obiekt { name: 'A-1', children: [ {name: "A-1-A"}, {name: "A-1-B"}, ] }

To nazywam tak searchFn(tree,'A-1-A'), powinno to zwrócić

{name: "A-1-A"}

Próbowałem w ten sposób, ale nie działałem

 function searchFn(obj ,searchText){
        if(obj.name === searchText) return obj
        if(obj.children.length > 0){
          return   searchFn(obj.children.pop(),searchText)
        }
      return null
    }
4
user944513 2 kwiecień 2020, 15:32

5 odpowiedzi

Najlepsza odpowiedź

Musisz wykonać iterację elementów potomnych obiektu i przyjąć zmienną jako wynik.

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; }
4
Nina Scholz 2 kwiecień 2020, 12:38

Najpierw powinieneś utworzyć klasę dla czytelności. Następnie powinieneś mieć pętlę wewnątrz funkcji, która iteruje po elementach potomnych i zwraca tylko wtedy, gdy dziecko zostanie znalezione.

    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"));
2
Alexandre Senges 2 kwiecień 2020, 13:00
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}
1
xdeepakv 2 kwiecień 2020, 12:47

Możesz spróbować czegoś takiego

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'))
1
Code Maniac 2 kwiecień 2020, 12:52

Problem z twoją funkcją polega na tym, że sprawdza ona tylko wyskakujący element z tablicy we właściwości children przekazanego obiektu, a nie inne elementy. Spróbuj tego:

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; 
}
0
Param Siddharth 2 kwiecień 2020, 12:55