首页 > 解决方案 > 如何根据多个嵌套条件过滤对象?

问题描述

我有以下对象,我正在尝试根据多个标准过滤并返回两个组的玩家,例如“向我展示所有玩家,其中特许经营 = 漫威,权力 = 飞行”,但我被挂断了多个过滤级别。

我在看这个答案,但它似乎不适合我的场景:JavaScript - Filter object based on multiple values

如果我遍历这些组,我可以获得结果,但可能有很多组,我不想被挂断。不过,这是最好的方法吗?

oPlayers.players.groups.filter(function(hero){return hero.Id == 1}) 
oPlayers = {
    "players": {
        "groups": [
            {
                "Id": 1,
                "hero": [
                    {
                        "Id": 1,
                        "name": "Batman",
                        "franchise": "DC", 
                        "gender": "Male", 
                        "powers": [{"power":"stealth"},{"power":"intelligence"},{"power":"weaponry"}]
                    },                  
                    {
                        "Id": 2,
                        "name": "Ironman",
                        "franchise": "Marvel", 
                        "gender": "Male", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"weaponry"}]
                    },          
                    {
                        "Id": 3,
                        "name": "Supergirl",
                        "franchise": "DC", 
                        "gender": "Female", 
                        "powers": [{"power":"flight"},{"power":"strength"},{"power":"speed"}]
                    },                  
                    {
                        "Id": 4,
                        "name": "Valkyrie",
                        "franchise": "Marvel", 
                        "gender": "Female", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"strength"}]
                    }           
                ]
            },
            {
                "Id": 2,
                "hero": [
                    {
                        "Id": 1,
                        "name": "Batwoman",
                        "franchise": "DC", 
                        "gender": "Female", 
                        "powers": [{"power":"stealth"},{"power":"intelligence"},{"power":"weaponry"}]
                    },                  
                    {
                        "Id": 2,
                        "name": "IronPepper",
                        "franchise": "Marvel", 
                        "gender": "Female", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"weaponry"}]
                    },              
                    {
                        "Id": 3,
                        "name": "Superman",
                        "franchise": "DC", 
                        "gender": "Male", 
                        "powers": [{"power":"flight"},{"power":"strength"},{"power":"speed"}]
                    },                  
                    {
                        "Id": 4,
                        "name": "Thor",
                        "franchise": "Marvel", 
                        "gender": "Male", 
                        "powers": [{"power":"flight"},{"power":"intelligence"},{"power":"strength"}]
                    }
                ]
            }
        ]
    }
}       

标签: javascriptarraysobject

解决方案


您可以首先使用flatMap获取所有玩家的单一列表。然后,假设您的条件被指定为一个对象,您可以根据every指定的属性是否criteria匹配玩家的属性来过滤玩家:

function filter(players, criteria) {
  return players.players.groups.flatMap(({Id, hero}) => 
    hero.filter(p =>
      Object.entries(criteria).every(([k, v]) => {
        if (k === 'power') return p.powers.some(({power}) => power === v);
        return p[k] === v;
      }))
      .map(p => ({groupId: Id, ...p})));
}

const oPlayers = {
  "players": {
    "groups": [{
        "Id": 1,
        "hero": [{
            "Id": 1,
            "name": "Batman",
            "franchise": "DC",
            "gender": "Male",
            "powers": [{
              "power": "stealth"
            }, {
              "power": "intelligence"
            }, {
              "power": "weaponry"
            }]
          },
          {
            "Id": 2,
            "name": "Ironman",
            "franchise": "Marvel",
            "gender": "Male",
            "powers": [{
              "power": "flight"
            }, {
              "power": "intelligence"
            }, {
              "power": "weaponry"
            }]
          },
          {
            "Id": 3,
            "name": "Supergirl",
            "franchise": "DC",
            "gender": "Female",
            "powers": [{
              "power": "flight"
            }, {
              "power": "strength"
            }, {
              "power": "speed"
            }]
          },
          {
            "Id": 4,
            "name": "Valkyrie",
            "franchise": "Marvel",
            "gender": "Female",
            "powers": [{
              "power": "flight"
            }, {
              "power": "intelligence"
            }, {
              "power": "strength"
            }]
          }
        ]
      },
      {
        "Id": 2,
        "hero": [{
            "Id": 1,
            "name": "Batwoman",
            "franchise": "DC",
            "gender": "Female",
            "powers": [{
              "power": "stealth"
            }, {
              "power": "intelligence"
            }, {
              "power": "weaponry"
            }]
          },
          {
            "Id": 2,
            "name": "IronPepper",
            "franchise": "Marvel",
            "gender": "Female",
            "powers": [{
              "power": "flight"
            }, {
              "power": "intelligence"
            }, {
              "power": "weaponry"
            }]
          },
          {
            "Id": 3,
            "name": "Superman",
            "franchise": "DC",
            "gender": "Male",
            "powers": [{
              "power": "flight"
            }, {
              "power": "strength"
            }, {
              "power": "speed"
            }]
          },
          {
            "Id": 4,
            "name": "Thor",
            "franchise": "Marvel",
            "gender": "Male",
            "powers": [{
              "power": "flight"
            }, {
              "power": "intelligence"
            }, {
              "power": "strength"
            }]
          }
        ]
      }
    ]
  }
};

console.log(filter(oPlayers, {gender: 'Male', franchise: 'Marvel'}));
console.log(filter(oPlayers, {gender: 'Female', power: 'flight'}));


推荐阅读