从任何级别的嵌套 json 数组中过滤对象,保留父数组层次结构

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

我有一个类似于以下结构的多级嵌套数组。 我想做的是过滤

'flag'
值为
'Gold'
的案例列表。 只有具有
type = 'Model' or type = 'Project'
的节点才会具有
type = 'Case'
具有
flag
值的直接子案例。

const models = [
    {
        "name": "Group1",
        "type": "Group",
        "cases": [
            {
                "name": "Model1",
                "type": "Model",
                "cases": [
                    {
                        "name": "Case1",
                        "type": "Case",
                        "flag": "Gold",
                        "cases": []
                    }
                ]
            },
            {
                "name": "Model2",
                "type": "Model",
                "cases": [
                    {
                        "name": "Project1",
                        "type": "Project",
                        "cases": [
                            {
                                "name": "Project2",
                                "type": "Project",
                                "cases": [
                                    {
                                        "name": "Case2",
                                        "type": "Case",
                                        "flag": "Gold",
                                        "cases": []
                                    },
                                    {
                                        "name": "Case3",
                                        "type": "Case",
                                        "flag": "Silver",
                                        "cases": []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "name": "Case4",
                        "type": "Case",
                        "flag": "Gold",
                        "cases": []
                    }
                ]
            },
        ]
    },
    {
        "name": "Group2",
        "type": "Group",
        "cases": [
            {
                "name": "Model3",
                "type": "Model",
                "cases": [
                    {
                        "name": "Case5",
                        "type": "Case",
                        "flag": "Gold",
                        "cases": []
                    }
                ]
            }
        ]
    }
]

例如,如果我只想过滤

flag = 'Gold'
的案例列表,结果如下所示。

Group1
    ...Model1
         { Case1 }
    ...Model2
        ...Project1
             ...Project2
                 { Case2 }
        { Case4 }
Group2
    ...Model3
        { Case5 }

我尝试了以下两种方法,但没有得到预期的结果。 使用

filter
选项。

 private getFilteredList(models: any[], term: string): any[] {
        const filterList = (data, term) => {
            data.filter((e) => {
                if (e.type === "Model" || e.type === "Project") {
                    e.cases = e.cases.filter(c => c.flag === term);
                }
                else if (e.cases) {
                    filterList(e.cases, term);
                }
            });
        }
        filterList(models, term);

        return models;
    }

使用

reduce
功能。这段代码导致无限循环。

private getFilteredList(models: any[], term: string): any[] {
        return models.reduce((list, item) => {
            if (item.flag === term) {
                list.push(item);
            } else if (item.cases && item.cases.length > 0) {
                const caseList = this.getFilteredList(item.cases, term);

                if (caseList.length > 0) {
                    list.push({ name: item.name, cases: caseList });
                }
            }

            return list;
        }, []);
    }

任何帮助表示赞赏。

javascript arrays json typescript filter
1个回答
0
投票

基本上,这将遍历树,寻找位于

flag === term
的项目。事实上,它返回 4 个项目
Gold
。这样就够了,还是还需要父母?

const models=[{name:"Group1",type:"Group",cases:[{name:"Model1",type:"Model",cases:[{name:"Case1",type:"Case",flag:"Gold",cases:[]}]},{name:"Model2",type:"Model",cases:[{name:"Project1",type:"Project",cases:[{name:"Project2",type:"Project",cases:[{name:"Case2",type:"Case",flag:"Gold",cases:[]},{name:"Case3",type:"Case",flag:"Silver",cases:[]}]}]},{name:"Case4",type:"Case",flag:"Gold",cases:[]}]},]},{name:"Group2",type:"Group",cases:[{name:"Model3",type:"Model",cases:[{name:"Case5",type:"Case",flag:"Gold",cases:[]}]}]}];


function getFilteredList(models, term) {
  var result = [];

  models.forEach(function(model) {
    if (model.type === 'Case' && model.flag === term) {
      result.push(model)
    }
    if (model.cases) {
      var inner = getFilteredList(model.cases, term)
      inner.forEach(function(item) {
        result.push(item)
      })
    }
  })

  return result;
}



console.log(getFilteredList(models, "Gold"))
.as-console-wrapper {
  min-height: 100%;
}

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