JS - 多维数组上的递归函数,仅过滤掉“选中”的项目(如果选择了子项,则过滤掉其父项)

问题描述 投票:0回答:1

我有这种数组(我称之为类别,它们也有 childCats)

var cats = [
  {
      "id": 1,
      "name": "A",
      "parentCategoryId": null,
      "parentCategory": null,
      "childCategories": [
          {
              "id": 2,
              "name": "B",
              "parentCategoryId": 1,
              "parentCategory": null,
              "childCategories": [
                  {
                      "id": 3,
                      "name": "C",
                      "parentCategoryId": 2,
                      "parentCategory": null,
                      "childCategories": []
                  },
                  {
                      "id": 4,
                      "name": "D",
                      "parentCategoryId": 2,
                      "parentCategory": null,
                      "childCategories": []
                  },
                  {
                      "id": 5,
                      "name": "E",
                      "parentCategoryId": 2,
                      "parentCategory": null,
                      "childCategories": []
                  }
              ]
          }
      ]
  },
  {
      "id": 66,
      "name": "BLA",
      "parentCategoryId": null,
      "parentCategory": null,
      "childCategories": []
  },  
  
];

我现在需要的是获取一个包含选中项(及其父项)的数组

这意味着,我只检查了“C”,我得到:

[
  {
      "name": "A",
      "childCategories": [
          {
              "name": "B",
              "childCategories": [
                  {
                      "name": "C",
                      "childCategories": []
                  }
              ]
          }
      ]
  }
]

如果我检查了“C”和“D”:

var cats = [
  {
      "name": "A",
      "childCategories": [
          {
              "name": "B",
              "childCategories": [
                  {
                      "name": "C",
                      "childCategories": []
                  },
                  {
                      "name": "D",
                      "childCategories": []
                  }
              ]
          }
      ]
  },    
];

对于“B”来说:

var cats = [
  {
      "name": "A",
      "childCategories": [
          {
              "name": "B",
              "childCategories": []
          }
      ]
  },    
];

我目前拥有的(感觉就像一团糟)是:(结果是console.log(..))

console.clear();
var checkedInterests = ['C'];
var checkedInterestsForDisplay = [];

var getInterestsForDisplay = function(arr) {
  for (var a of arr) {
    if (checkedInterests.includes(a.name)) {
      a.childCategories = [];
      checkedInterestsForDisplay.push(a);

      //also if a child is checked, the parent should be expanded
      var getParents = function(arrayToFindParent, parentIdToFind) {
        for (var aTFP of arrayToFindParent) {
          if (aTFP.id == parentIdToFind) {
            aTFP.childCategories = checkedInterestsForDisplay;
            checkedInterestsForDisplay = [aTFP];
            //again check if it has parents
            getParents(cats, aTFP.parentCategoryId);
          } else {
            getParents(aTFP.childCategories, parentIdToFind);
          }
        }
      }
      getParents(cats, a.parentCategoryId);
    }
    getInterestsForDisplay(a.childCategories);
  }
}

getInterestsForDisplay(cats);

console.log('checkedInterestsForDisplay', checkedInterestsForDisplay);
<script>
var cats = [{
    "id": 1,
    "name": "A",
    "parentCategoryId": null,
    "parentCategory": null,
    "childCategories": [{
      "id": 2,
      "name": "B",
      "parentCategoryId": 1,
      "parentCategory": null,
      "childCategories": [{
          "id": 3,
          "name": "C",
          "parentCategoryId": 2,
          "parentCategory": null,
          "childCategories": []
        },
        {
          "id": 4,
          "name": "D",
          "parentCategoryId": 2,
          "parentCategory": null,
          "childCategories": []
        }
      ]
    }]
  },
  {
    "id": 66,
    "name": "BLA",
    "parentCategoryId": null,
    "parentCategory": null,
    "childCategories": []
  },
];
</script>

这工作正常,但是如果

var checkedInterests = ['C','D'];

我明白了

超出最大调用堆栈大小

javascript
1个回答
0
投票

您可以简化代码以从孩子那里获取项目,或者检查实际的根。如果其中一个有一些想要的项目,则返回带有过滤子项的对象。

const
    data = [{ id: 1, name: "A", parentCategoryId: null, parentCategory: null, childCategories: [{ id: 2, name: "B", parentCategoryId: 1, parentCategory: null, childCategories: [{ id: 3, name: "C", parentCategoryId: 2, parentCategory: null, childCategories: [] }, { id: 4, name: "D", parentCategoryId: 2, parentCategory: null, childCategories: [] }, { id: 5, name: "E", parentCategoryId: 2, parentCategory: null, childCategories: [] }] }] }, { id: 66, name: "BLA", parentCategoryId: null, parentCategory: null, childCategories: [] }],
    filter = (data, names) => data.reduce((r, o) => {
        const
            childCategories = filter(o.childCategories, names);
            
        if (names.includes(o.name) || childCategories.length) r.push({ ...o, childCategories });
        
        return r;
    }, []);
    
console.log(filter(data, ['A']));
console.log(filter(data, ['B']));
console.log(filter(data, ['C', 'D']));
console.log(filter(data, ['BLA', 'C', 'D']));
.as-console-wrapper { max-height: 100% !important; top: 0; }

© www.soinside.com 2019 - 2024. All rights reserved.