如何根据多个嵌套条件过滤对象?

时间:2019-10-01 22:15:50

标签: javascript arrays object

我有以下对象,并且我试图根据多个条件(例如,“向我显示所有拥有特许经营=奇迹,实力=飞行的球员”),从两个组中筛选并退回球员,但我却垂头丧气在多个级别的过滤中。

我在看这个答案,但似乎不适合我的情况: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"}]
                    }
                ]
            }
        ]
    }
}       

1 个答案:

答案 0 :(得分:1)

您可以先使用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'}));