javascript - Javascript 复杂数组过滤器
问题描述
我有这个对象数组,它们都有嵌套数组,每个元素都有另一个数组,每个元素都有一个......你明白了。深层嵌套数组。
让我通过一个例子来解释我想要实现的目标。我有一个组列表。每个组都有一个英雄列表,每个英雄都有一个力量列表,每个力量都有一个优势列表。
我希望能够使用 mat-stepper 迭代每一步选择组,然后选择英雄,然后是力量,最后是力量。因此,当从 mat-select 中选择一个组时,在下一步中,mat-select 将只保留属于该组的英雄,依此类推,直到力量。
该组列表的示例可能如下所示:
[
{
"id": "g1",
"group": "1",
"heroes": [
{
"id": "g1h1",
"hero": "hero1",
"powers": [
{
"id": "g1h1p1",
"power": "pyromancy",
"strengths": [
{
"id": "g1h1p1s1",
"strength": "undead"
}
]
},
{
"id": "g1h1p2",
"power": "light",
"strengths": [
{
"id": "g1h1p2s1",
"strength": "shadow people"
},
{
"id": "g1h1p2s2",
"strength": "guidence"
}
]
}
]
},
{
"id": "g1h2",
"hero": "hero2",
"powers": []
}
]
},
{
"id": "g2",
"group": "2",
"heroes": [
{
"id": "g2h1",
"hero": "hero1",
"powers": [
{
"id": "g2h1p1",
"power": "electromancy",
"strengths": [
{
"id": "g2h1p1s1",
"strength": "metal armor"
},
{
"id": "g2h1p1s2",
"strength": "metal shields"
}
]
},
{
"id": "g2h1p2",
"power": "invisibility",
"strengths": []
}
]
}
]
},
{
"id": "g3",
"group": "group3",
"heroes": []
}
]
列表中的每个元素都有自己的唯一 ID。好消息是我已经实施并工作了。但是,我希望能够根据所有已选择的内容以及仅具有优势的那些权力来过滤选择。
所以删除要求如下:
- 如果力量已经全部添加到所选力量列表中,则将其作为可能的选择删除
- 如果在任何时候某个元素有一个空列表,则将其作为可能的选择删除。因此,如果一个权力没有优势或英雄没有权力,则将其移除。
因此,使用上面的示例,如果我选择的列表全部准备好包含不死族、影子人和金属盾牌(id 值,而不是实际文本),那么我期望返回的过滤列表应该是这样的:
[
{
"id": "g1",
"group": "1",
"heroes": [
{
"id": "g1h1",
"hero": "hero1",
"powers": [
{
"id": "g1h1p1",
"power": "light",
"strengths": [
{
"id": "g1h1p1s1",
"strength": "guidence"
}
]
}
]
}
]
},
{
"id": "g2",
"group": "2",
"heroes": [
{
"id": "g2h1",
"hero": "hero1",
"powers": [
{
"id": "g2h1p1",
"power": "electromancy",
"strengths": [
{
"id": "g2h1p1s1",
"strength": "metal armor"
}
]
}
]
}
]
}
]
我已经尝试了很多尝试,但我只是没有得到正确的结果。以下是我的尝试之一。我究竟做错了什么?还是有更好的方法来做到这一点?
filterGroups()
{
//Iterate groups
this.groups.forEach(group => {
//remove empty groups
if(group.heroes.length === 0)
{
let groupIndex: number = this.groups.findIndex(x => x.id === group.id);
this.groups.splice(groupIndex, 1);
}
else {
group.heroes.forEach(hero => {
//remove heroes with no powers
if(hero.powers.length === 0)
{
let heroIndex: number = group.heroes.findIndex(h => h.id === hero.id);
group.heroes.splice(heroIndex, 1);
}
else {
hero.powers.forEach(power => {
//remove powers with no strengths
if(power.strengths.length === 0)
{
let powerIndex: number = hero.powers.findIndex(p => p.id === power.id);
hero.powers.splice(powerIndex,1);
}
else {
power.strengths.forEach(strength => {
if(this.selectedStrengths.some(x => x === strength.id))
{
let strengthIndex: number = power.strengths.findIndex(s => s.id === strength.id);
if(strengthIndex>-1)
{
power.strengths.splice(strengthIndex,1);
}
}
})
//check if power is empty after filtering strengths
if(power.strengths.length === 0)
{
let powerIndex: number = hero.powers.findIndex(p => p.id === power.id);
hero.powers.splice(powerIndex,1);
}
}
});
//Check hero is empty after filtering powers
if(hero.powers.length === 0)
{
let heroIndex: number = group.heroes.findIndex(h => h.id === hero.id);
group.heroes.splice(heroIndex, 1);
}
}
});
//Check if group is empty after filtering heroes
if(group.heroes.length === 0)
{
let groupIndex: number = this.groups.findIndex(x => x.id === group.id);
this.groups.splice(groupIndex, 1);
}
}
});
}
解决方案
filterGroups() {
return this.groups.filter(g => {
g.heroes = g.heroes.filter(h => {
h.powers = h.powers.filter(p => {
p.strengths = p.strengths.filter(s => this.selectedStrengths.indexOf(s.id) === -1);
return p.strengths.length > 0
})
return h.powers.length > 0;
})
return g.heroes.length > 0
})
}
推荐阅读
- javascript - Javascript代码在我的项目中不起作用
- reactjs - 反应本机 navigation.state.params 总是未定义
- html - IE中奇怪的换行行为
- dart - 添加延迟构建未来
- python - 使用 ColumTransformer 进行虚拟编码
- jquery - Shopify Ajax API - /cart/update.js 无法更新产品数量
- c# - 选择选项在卡片末尾消失
- elasticsearch - ELK - 如何从日志文件中选择时间戳而不是插入的时间戳
- docker - Jenkins & GitLab & Docker 集成失败
- android - 在 Kotlin、Android 中重用方法