Find an element in an array recursively

后端 未结 3 1337
情深已故
情深已故 2021-01-04 05:55

I have an array of objects. Every object in the array has an id and an item property that is an array containing other object. I need to be able to find an element in an arr

相关标签:
3条回答
  • 2021-01-04 06:26

    yeah thanks but I have an issue if there is a nested array like you wanna build a menu panel yourself and wanna get an item with a specific id no matter where is it

    example : var treeDataSource = [ { Id: 1, Name: "s", Children: [ { Id: 2, Name: "m", Children: [ { Id: 3, Name: "q", Children: [ { Id: 4, Name: "a", Children: [ { Id: 5, Name: "w", Children: [ { Id: 6, Name: "needed", Children: [], } ], } ], } ], } ], } ], }, ] I wanna return the item matches Id 6

    0 讨论(0)
  • 2021-01-04 06:34

    I know its late but here is a more generic approach

    Array.prototype.findRecursive = function(predicate, childrenPropertyName){
        if(!childrenPropertyName){
            throw "findRecursive requires parameter `childrenPropertyName`";
        }
        let array = [];
        array = this;
        let initialFind =  array.find(predicate);
        let elementsWithChildren  = array.filter(x=>x[childrenPropertyName]);
        if(initialFind){
            return initialFind;
        }else if(elementsWithChildren.length){
            let childElements = [];
            elementsWithChildren.forEach(x=>{
                childElements.push(...x[childrenPropertyName]);
            });
            return childElements.findRecursive(predicate, childrenPropertyName);
        }else{
            return undefined;
        }
    }
    

    to use it:

    var array = [<lets say an array of students who has their own students>];
    var joe = array.findRecursive(x=>x.Name=="Joe", "students");
    

    and if you want filter instead of find

    Array.prototype.filterRecursive = function(predicate, childProperty){
        let filterResults = [];
        let filterAndPushResults = (arrayToFilter)=>{
            let elementsWithChildren  = arrayToFilter.filter(x=>x[childProperty]);
            let filtered = arrayToFilter.filter(predicate);
            filterResults.push(...filtered);
            if(elementsWithChildren.length){
                let childElements = [];
                elementsWithChildren.forEach(x=>{
                    childElements.push(...x[childProperty]);
                });
                filterAndPushResults(childElements);
            }
        };
        filterAndPushResults(this);
        return filterResults;
    }
    
    0 讨论(0)
  • 2021-01-04 06:36

    You should replace

      getSubMenuItem(subMenuItems[i].items, id);
    

    with

      var found = getSubMenuItem(subMenuItems[i].items, id);
      if (found) return found;
    

    in order to return the element when it is found.

    And be careful with the name of the properties, javascript is case sensitive, so you must also replace

      if (subMenuItems[i].Id == id) {
    

    with

      if (subMenuItems[i].id == id) {
    

    Demonstration


    Final (cleaned) code :

    var getSubMenuItem = function (subMenuItems, id) {
        if (subMenuItems) {
            for (var i = 0; i < subMenuItems.length; i++) {
                if (subMenuItems[i].id == id) {
                    return subMenuItems[i];
                }
                var found = getSubMenuItem(subMenuItems[i].items, id);
                if (found) return found;
            }
        }
    };
    
    0 讨论(0)
提交回复
热议问题