簡體   English   中英

遞歸查找數組中的元素

[英]Find an element in an array recursively

我有一個對象數組。 數組中的每個對象都有一個 id 和一個 item 屬性,該屬性是一個包含其他對象的數組。 我需要能夠通過 id 在數組中找到一個元素。 這是我到目前為止所做的示例,但遞歸函數始終返回未定義。

當我多次遞歸調用該函數時,如何退出該函數並返回該項目?

   $(function () {
    var treeDataSource = [{
        id: 1,
        Name: "Test1",
        items: [{
            id: 2,
            Name: "Test2",
            items: [{
                id: 3,
                Name: "Test3"
            }]
        }]
    }];
    var getSubMenuItem = function (subMenuItems, id) {
        if (subMenuItems && subMenuItems.length > 0) {
            for (var i = 0; i < subMenuItems.length; i++) {
                var item;
                if (subMenuItems[i].Id == id) {
                    item = subMenuItems[i];
                    return item;
                };
                getSubMenuItem(subMenuItems[i].items, id);
            };
        };
    };
    var searchedItem = getSubMenuItem(treeDataSource, 3);
    alert(searchedItem.id);
});

js小提琴

你應該更換

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

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

為了在找到元素時返回元素。

並注意屬性的名稱,javascript區分大小寫,因此您還必須替換

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

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

示范


最終(清理)代碼:

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;
        }
    }
};

我知道它晚了,但這里有一個更通用的方法

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;
    }
}

使用它:

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

如果你想過濾而不是查找

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;
}

是的,謝謝,但我有一個問題,如果有一個嵌套數組,比如你想自己構建一個菜單面板,並想獲得一個具有特定 id 的項目,無論它在哪里

示例: 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: [], } ], } ], } ], } ], } ], }, ]我想返回匹配 Id 6 的項目

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM