Как мне отфильтровать объект по нескольким вложенным критериям? - PullRequest
0 голосов
/ 02 октября 2019

У меня есть следующий объект, и я пытаюсь отфильтровать и вернуть игроков из обеих групп по нескольким критериям, таким как «показать мне всех игроков, где франшиза = Marvel и сила = полет», но я зависаюна нескольких уровнях фильтрации.

Я смотрел на этот ответ, но он не подходит для моего сценария: JavaScript - Фильтровать объект по нескольким значениям

Я могу получить результаты, если переберунад группами, но потенциально много групп, и я не хотел зацикливаться на этом. Это лучший способ?

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 Ответ

1 голос
/ 02 октября 2019

Вы можете сначала использовать 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'}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...