首页 > 解决方案 > Javascript 复杂数组过滤器

问题描述

我有这个对象数组,它们都有嵌套数组,每个元素都有另一个数组,每个元素都有一个......你明白了。深层嵌套数组。

让我通过一个例子来解释我想要实现的目标。我有一个组列表。每个组都有一个英雄列表,每个英雄都有一个力量列表,每个力量都有一个优势列表。

我希望能够使用 mat-stepper 迭代每一步选择组,然后选择英雄,然后是力量,最后是力量。因此,当从 mat-select 中选择一个组时,在下一步中,mat-select 将只保留属于该组的英雄,依此类推,直到力量。

该组列表的示例可能如下所示:

[
  {
    "id": "g1",
    "group": "1",
    "heroes": [
      {
        "id": "g1h1",
        "hero": "hero1",
        "powers": [
          {
            "id": "g1h1p1",
            "power": "pyromancy",
            "strengths": [
              {
                "id": "g1h1p1s1",
                "strength": "undead"
              }
            ]
          },
          {
            "id": "g1h1p2",
            "power": "light",
            "strengths": [
              {
                "id": "g1h1p2s1",
                "strength": "shadow people"
              },
              {
                "id": "g1h1p2s2",
                "strength": "guidence"
              }
            ]
          }
        ]
      },
      {
        "id": "g1h2",
        "hero": "hero2",
        "powers": []
      }
    ]
  },
  {
    "id": "g2",
    "group": "2",
    "heroes": [
      {
        "id": "g2h1",
        "hero": "hero1",
        "powers": [
          {
            "id": "g2h1p1",
            "power": "electromancy",
            "strengths": [
              {
                "id": "g2h1p1s1",
                "strength": "metal armor"
              },
              {
                "id": "g2h1p1s2",
                "strength": "metal shields"
              }
            ]
          },
          {
            "id": "g2h1p2",
            "power": "invisibility",
            "strengths": []
          }
        ]
      }
    ]
  },
  {
    "id": "g3",
    "group": "group3",
    "heroes": []
  }
]

列表中的每个元素都有自己的唯一 ID。好消息是我已经实施并工作了。但是,我希望能够根据所有已选择的内容以及仅具有优势的那些权力来过滤选择。

所以删除要求如下:

因此,使用上面的示例,如果我选择的列表全部准备好包含不死族影子人和金属盾牌(id 值,而不是实际文本),那么我期望返回的过滤列表应该是这样的:

[
  {
    "id": "g1",
    "group": "1",
    "heroes": [
      {
        "id": "g1h1",
        "hero": "hero1",
        "powers": [
          {
            "id": "g1h1p1",
            "power": "light",
            "strengths": [
              {
                "id": "g1h1p1s1",
                "strength": "guidence"
              }
            ]
          }
        ]
      }
    ]
  },
  {
  "id": "g2",
  "group": "2",
  "heroes": [
      {
        "id": "g2h1",
        "hero": "hero1",
        "powers": [
            {
              "id": "g2h1p1",
              "power": "electromancy",
              "strengths": [
                  {
                    "id": "g2h1p1s1",
                    "strength": "metal armor"
                  }
                ]
            }
          ]
      }
    ]
  }
]

我已经尝试了很多尝试,但我只是没有得到正确的结果。以下是我的尝试之一。我究竟做错了什么?还是有更好的方法来做到这一点?

  filterGroups()
  {
    //Iterate groups
    this.groups.forEach(group => {

      //remove empty groups
      if(group.heroes.length === 0)
      {
        let groupIndex: number = this.groups.findIndex(x => x.id === group.id);
        this.groups.splice(groupIndex, 1);
      }
      else {
        group.heroes.forEach(hero => {
          //remove heroes with no powers
          if(hero.powers.length === 0)
          {
            let heroIndex: number = group.heroes.findIndex(h => h.id === hero.id);
            group.heroes.splice(heroIndex, 1);
          }
          else {
            hero.powers.forEach(power => {
              //remove powers with no strengths
              if(power.strengths.length === 0)
              {
                let powerIndex: number = hero.powers.findIndex(p => p.id === power.id);
                hero.powers.splice(powerIndex,1);
              }            
              else {
                power.strengths.forEach(strength => {
                    if(this.selectedStrengths.some(x => x === strength.id))
                    {
                      let strengthIndex: number = power.strengths.findIndex(s => s.id === strength.id);
                      if(strengthIndex>-1)
                      {
                        power.strengths.splice(strengthIndex,1);
                      }
                    }              
                })

                //check if power is empty after filtering strengths
                if(power.strengths.length === 0)
                {
                  let powerIndex: number = hero.powers.findIndex(p => p.id === power.id);
                  hero.powers.splice(powerIndex,1);
                }
              }
            });

            //Check hero is empty after filtering powers
            if(hero.powers.length === 0)
            {
              let heroIndex: number = group.heroes.findIndex(h => h.id === hero.id);
              group.heroes.splice(heroIndex, 1);
            }
          }
        });

        //Check if group  is empty after filtering heroes
        if(group.heroes.length === 0)
        {
          let groupIndex: number = this.groups.findIndex(x => x.id === group.id);
          this.groups.splice(groupIndex, 1);
        }
      }
    });
  }

标签: javascriptangular

解决方案


    filterGroups() {
        return this.groups.filter(g => {
            g.heroes = g.heroes.filter(h => {
                h.powers = h.powers.filter(p => {
                    p.strengths = p.strengths.filter(s => this.selectedStrengths.indexOf(s.id) === -1);
                    return p.strengths.length > 0
                })
                return h.powers.length > 0;
            })
            return g.heroes.length > 0
        })
    }

推荐阅读