skip to Main Content

I have a tree object like below, and I need to search through it. I know there’s already some answers on topics like this here, but they are, unfortunately, do not comply with my structure.

const tree = {
    "28": {
        "label": "lorem"
        "children": {
            "188": {
                "label": "ipsum"
                "children": {
                    "482": {
                        "label": "fish"
                        "children": {
                            "185": {
                                "label": "dog"
                            },
                            "289": {
                                "label": "cat"
                            }
                        }
                    }
                }
            }
        }
    },
    "33": {
        "label": "water"
        "children": {
            "95": {
                "label": "fire"
                "children": {
                    "181": {
                        "label": "gas"
                        "children": {
                            "100": {
                                "label": "station"
                            }
                        }
                    }
                    "182": {
                        "label": ""
                        "children": {
                            "100": {
                                "label": "sushi"
                            }
                        }
                    }
                }
            }
        }
    }
}

For example, if I’ll search for ‘fish’, output should be like this:

{
    "28": {
        "label": "lorem"
        "children": {
            "188": {
                "label": "ipsum"
                "children": {
                    "482": {
                        "label": "fish"
                        "children": {
                            "185": {
                                "label": "dog"
                            },
                            "289": {
                                "label": "cat"
                            }
                        }
                    }
                }
            }
        }
    }
}

And if I’ll search for ‘dog’ instead:

{
    "28": {
        "label": "lorem"
        "children": {
            "188": {
                "label": "ipsum"
                "children": {
                    "482": {
                        "label": "fish"
                        "children": {
                            "185": {
                                "label": "dog"
                            }
                        }
                    }
                }
            }
        }
    }
}

I tried to use these gentlemen’s answers, but couldn’t adapt them to named objects:

How to filter a tree structure while keeping the decendants of the parents that are filtered out?

A Javascript function to filter tree structured json with a search term. exclude any object which donot match the search term

2

Answers


  1. To search through the tree structure and preserve its hierarchy, you can use a recursive function that:

    1. Checks if the current node’s label matches the search term.
    2. If not, it then checks its children.
    3. If a child matches the search term or any of its descendants match the term, it retains that child and continues searching deeper

    Here is an example of a solution:

    function filterTree(inputTree, searchTerm) {
        let resultTree = {};
    
        for (let key in inputTree) {
            let node = inputTree[key];
            
            // If the current label matches, it will return the entire subtree
            if (node.label === searchTerm) {
                resultTree[key] = node;
            } else {
                // Otherwise it will check the children
                let childrenResult = node.children ? filterTree(node.children, searchTerm) : {};
    
                // If any children matched, it will include this node in the result
                // but only with those children that matched
                if (Object.keys(childrenResult).length) {
                    resultTree[key] = { ...node, children: childrenResult };
                }
            }
        }
    
        return resultTree;
    }
    
    
    // Example of a usage
    const searchTerm = 'fish';
    const result = filterTree(tree, searchTerm);
    console.log(result);
    

    You can replace the searchTerm with ‘dog’ or any other creature you like and it should work.

    Login or Signup to reply.
  2. Use a recursive function that searches in the children property recursively.
    Note that we don’t use here spread syntax and functional approach since it would be slower.

    const search = (obj, str) => {
    
      for(const key in obj){
        const item = obj[key];
    
        if(item.label === str){
          return {[key]: item };
        }
        if(item.children){
          const found = search(item.children, str);
          if(found){
            return {[key]: Object.assign({}, item, {children: found})};
          }
        }
      }
      return null;
    };
    
    ['fish', 'dog', 'dummy'].forEach(str => console.log(str, search(tree, str)));
    <script>
    const tree = {
        "28": {
            "label": "lorem",
            "children": {
                "188": {
                    "label": "ipsum",
                    "children": {
                        "482": {
                            "label": "fish",
                            "children": {
                                "185": {
                                    "label": "dog"
                                },
                                "289": {
                                    "label": "cat"
                                }
                            }
                        }
                    }
                }
            }
        },
        "33": {
            "label": "water",
            "children": {
                "95": {
                    "label": "fire",
                    "children": {
                        "181": {
                            "label": "gas",
                            "children": {
                                "100": {
                                    "label": "station"
                                }
                            }
                        },
                        "182": {
                            "label": "",
                            "children": {
                                "100": {
                                    "label": "sushi"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search