【问题标题】:How to filter array based on nested value in Javascript如何根据Javascript中的嵌套值过滤数组
【发布时间】:2021-04-14 23:48:46
【问题描述】:

我有一个数组,我试图根据某个嵌套值进行过滤,而不获取任何其他元素。

const arrayData = [ 
{ 
    country: "Country X", 
    games: [ 
        { 
            gameTitle: 'Game1', 
            players: [{ name: 'John', status:'Active' },{ name: 'Rob', status:'Suspended' }] 
        }, 
        { 
            gameTitle: 'Game2', 
            players: [{ name: 'Saly', status:'Blocked' }] 
        }, 
    ] 
}, 
{ 
    country: "Country Y", 
    games: [ 
        { 
            gameTitle: 'Game1', 
            players: [{ name: 'Sindy', status:'Pending' },{ name: 'someone', status:'Rejected' }] 
        }, 
        { 
            gameTitle: 'Game2', 
            players: [{ name: 'Alex', status:'New' },{ name: 'Nic', status:'Old' }] 
        }, 
    ] 
}, 
]; 

我尝试过的:

let output = arrayData.filter(eachVal => { 
let opt = eachVal.games.some(( 
    { players }) => players 
    .some(({ status}) => status === 'Active')); 
return opt; 
}) 

查找具有 status 值的 所有玩家 的预期结果:'Active':

{ 
country: "Country X", 
games: [ 
    { 
        gameTitle: 'Game1', 
        players: [{ name: 'John', status:'Active' }] 
    }
] 
}

但是结果:

[{"country":"Country X","games":[{"gameTitle":"Game1","players":[{"name":"John","status":"Active"},{"name":"Rob","status":"Suspended"}]},{"gameTitle":"Game2","players":[{"name":"Saly","status":"Blocked"}]}]}]

【问题讨论】:

  • 嗯,如果你想要活跃状态的玩家,你为什么要国家和游戏数组?
  • @TheBombSquad 因为我也需要展示他们的价值观!
  • @Sam 这个问题可能会帮助stackoverflow.com/questions/38375646/…
  • 我以前见过,但过滤器仅适用于第一级,我无法在玩家列表中执行此操作。 @OzgurSar
  • 刚刚解决了.. 我使用的嵌套过滤逻辑

标签: javascript arrays


【解决方案1】:

逻辑是嵌套过滤器通过每个级别并将发现分配回各自的位置,并使用forEach 逻辑查看对象是否具有“活动”值

const arrayData = [ 
{ 
    country: "Country X", 
    games: [ 
        { 
            gameTitle: 'Game1', 
            players: [{ name: 'John', status:'Active' },{ name: 'Rob', status:'Suspended' }] 
        }, 
        { 
            gameTitle: 'Game2', 
            players: [{ name: 'Saly', status:'Blocked' }] 
        }, 
    ] 
}, 
{ 
    country: "Country Y", 
    games: [ 
        { 
            gameTitle: 'Game1', 
            players: [{ name: 'Sindy', status:'Pending' },{ name: 'someone', status:'Rejected' }] 
        }, 
        { 
            gameTitle: 'Game2', 
            players: [{ name: 'Alex', status:'New' },{ name: 'Nic', status:'Old' }] 
        }, 
    ] 
}, 
];

//answer
let arr=JSON.parse(JSON.stringify(arrayData))
arr=arr.filter(a=>{
  let f=a.games; let i=false
  f=f.filter(b=>{
    let x=b.players; let j=false
    x=x.filter(c=>c.status=="Active")
    x.forEach(c=>{if(c.status=="Active"){j=true}})
    b.players=x; return j
  })
  f.forEach(b=>{
    b.players.forEach(c=>{if(c.status=="Active"){i=true}})
  })
  a.games=f; return i
})
console.log(arr)

【讨论】:

    【解决方案2】:

    我会“递归”选择每个级别的有效元素并映射到每个过滤后的数组以构建正确的输出:

    const selectActivePlayers = (players) => players.filter(player => player.status === "Active");
    const selectValidGames = (games) => games.filter(game => selectActivePlayers(game.players).length > 0)
    const selectValidCountries = (countries) => countries.filter(country => selectValidGames(country.games).length > 0);
    
    
    const cleanCountries = selectValidCountries(arrayData).map(country => ({
      ...country,
      games: selectValidGames(country.games).map(game => ({
        ...game,
        players: selectActivePlayers(game.players)
      }))
    }))
    

    输出:

    [
      {
        "country": "Country X",
        "games": [
          {
            "gameTitle": "Game1",
            "players": [
              {
                "name": "John",
                "status": "Active"
              }
            ]
          }
        ]
      }
    ]
    

    【讨论】:

      【解决方案3】:

      这很容易。你只需要一些map 和filter:

      const arrayData = [ 
      { 
          country: "Country X", 
          games: [ 
              { 
                  gameTitle: 'Game1', 
                  players: [{ name: 'John', status:'Active' },{ name: 'Rob', status:'Suspended' }] 
              }, 
              { 
                  gameTitle: 'Game2', 
                  players: [{ name: 'Saly', status:'Blocked' }] 
              }, 
          ] 
      }, 
      { 
          country: "Country Y", 
          games: [ 
              { 
                  gameTitle: 'Game1', 
                  players: [{ name: 'Sindy', status:'Pending' },{ name: 'someone', status:'Rejected' }] 
              }, 
              { 
                  gameTitle: 'Game2', 
                  players: [{ name: 'Alex', status:'New' },{ name: 'Nic', status:'Old' }] 
              }, 
          ] 
      }, 
      ];
      
      /*------------------------------- This is the answer -------------------------------*/
      let result = arrayData.map(a => ({...a, games: a.games.map(g => ({...g, players: g.players.filter(p => p.status === 'Active')})).filter(g => g.players.length)})).filter(a => a.games.length)
      /*----------------------------------------------------------------------------------*/
      console.log(result)

      【讨论】:

        【解决方案4】:

        试试这个:

        arrayData.map(({country, games: g}) => {
          
          const games = g.map((g) => { 
            const players = g.players.filter((p) => p.status === 'Active')
          
            return {...g, players}
          })
          .filter(({players}) => players.length > 0)
          
          return {country, games}
        }).filter(({games}) => games.length>0)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-06
          • 1970-01-01
          • 2019-08-10
          • 1970-01-01
          • 2022-12-07
          • 2017-09-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多