使用normalizr
库后,在我的应用程序的Redux状态下,我有以下标准化的JSON对象结果:
{
sports: {
byId: {
1: {
id: 1,
name: 'Soccer',
slug: 'soccer'
},
2: {
id: 2,
name: 'Basketball',
slug: 'basketball'
},
3: {
id: 3,
name: 'American Football',
slug: 'american-football'
}
},
allIds: [
'1',
'2',
'3'
]
},
competitions: {
byId: {
'1': {
id: 1,
name: 'Competition 1',
short_name: 'Comp 1',
slug: 'comp-1',
sport: 1,
status: {
is_live: false
}
},
'2': {
id: 2,
name: 'Competition 2',
short_name: 'Comp 2',
slug: 'comp-2',
sport: 1,
status: {
is_live: true
}
},
'3': {
id: 3,
name: 'National Basketball League',
short_name: 'NBA',
slug: 'national-basketball-league',
sport_slug: 'basketball',
sport: 3,
status: {
is_live: true
}
}
},
allIds: [
'1',
'2',
'3'
]
}
我要实现的目标:我需要由
competitions
过滤/分类的sports
列表。我怎样才能做到这一点?
我也希望能够通过
competitions
对status.is_live
进行分组。那么,如何获取按
competitions
等于true和sport
status.is_live
等于false的competitions
细分的status.is_live
列表?任何帮助表示赞赏!谢谢
最佳答案
如果不想使用lodash,则可以很容易地编写.groupBy
函数(example)。您需要遍历输出对象,并使用for而不是使用.mapValues
来重新分配其子级值。
我在示例中使用了lodash,只是为了指出逻辑。
注意:我将删除原始响应中的数据分组,然后让客户端自行执行操作-在未排序的数组和过滤器/映射上进行操作比在具有冗余对象的值上进行处理更容易键(因为它们代表按ID分组)
let data = {
sports: {
byId: {
1: {
id: 1,
name: 'Soccer',
slug: 'soccer'
},
2: {
id: 2,
name: 'Basketball',
slug: 'basketball'
},
3: {
id: 3,
name: 'American Football',
slug: 'american-football'
}
},
allIds: [
'1',
'2',
'3'
]
},
competitions: {
byId: {
'1': {
id: 1,
name: 'Competition 1',
short_name: 'Comp 1',
slug: 'comp-1',
sport: 1,
status: {
is_live: false
}
},
'2': {
id: 2,
name: 'Competition 2',
short_name: 'Comp 2',
slug: 'comp-2',
sport: 1,
status: {
is_live: true
}
},
'3': {
id: 3,
name: 'National Basketball League',
short_name: 'NBA',
slug: 'national-basketball-league',
sport_slug: 'basketball',
sport: 3,
status: {
is_live: true
}
}
},
allIds: [
'1',
'2',
'3'
]
}
}
let competitions = Object.values(data.competitions.byId)
// _.chain(arr) keeps returning `lodash` objects
// so I don't have to call it separately for every action
let filteredCompetitions = _.chain(competitions)
.groupBy(i => i.status.is_live)
.mapValues(i => _.groupBy(i, 'sport'))
.value() // returns the final value
console.log(filteredCompetitions)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>