[英]How to filter array based on nested value in Javascript
我有一個數組,我試圖根據某個嵌套值進行過濾,而不獲取任何其他元素。
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;
})
查找所有具有值狀態的玩家的預期結果: “活動” :
{
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"}]}]}]
嘗試這個:
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)
該邏輯是嵌套過濾器通過每個級別並將發現分配回各自的位置並使用forEach
邏輯查看 object 是否具有“活動”值
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)
我會“遞歸” select 每個級別的有效元素和每個過濾數組上的 map 以構建正確的 output:
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)
}))
}))
Output:
[
{
"country": "Country X",
"games": [
{
"gameTitle": "Game1",
"players": [
{
"name": "John",
"status": "Active"
}
]
}
]
}
]
這很容易。 你只需要一些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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.