javascript - 如何过滤数组并添加到新数组
问题描述
我有一个名为“infos”的对象数组,在这个对象数组中我有一个名为 TagId 的元素。我有另一个名为“TagIds”的数组,它在任何给定时间都包含 0-3 个 ID。我想遍历我的“infos”数组中的每个对象,如果有匹配项,则将该对象添加到我的“filteredResults”数组中。
现在我通过以下代码实现了这一点:
infos: Array<{InfoPageId: number, DepartmentId: number, Name: string, Url: string, Html: string, Title: string, Keywords: string, Description: string, InfoTypeId: number, DateCreated: Date, DateUpdated: Date, Hidden: boolean, AMPhtml: string, UseAmp: boolean, UseAmpVideo: boolean, UseCarousel: boolean, TradeOnly: boolean, TagId: number}> = [];
TagIds = [];
getBuyingGuidesNotFiltered() {
this.IsWait = true;
this._SharedService.getAll().subscribe((data: any[]) => {
data.forEach(e => {
if(e.InfoTypeId === 12)
{
this.infos.push(new infoPage(
e.InfoPageId,
e.DepartmentId,
e.Name,
e.Url,
e.Html,
e.Title,
e.Keywords,
e.Description,
e.InfoTypeId,
e.DateCreated,
e.DateUpdated,
e.Hidden,
e.AMPhtml,
e.UseAmp,
e.UseAmpVideo,
e.UseCarousel,
e.TradeOnly,
e.TagId
));
}
})
this.getFiltered(this.infos);
this.IsWait = false;
});
}
getFiltered(infos: Array<infoPage>) {
var filteredResults = []
for(var i = 0; i < this.infos.length; i++) {
for(var j = 0; j < this.TagIds.length; j++) {
if(this.infos[i].TagId === this.TagIds[j]) {
filteredResults.push(this.infos[i]);
}
}
}
this.infos = [];
this.infos = filteredResults;
}
现在的问题是我的对象数组“信息”包含重复数据,例如:
this.infos = [
{InfoPageId: 8, DepartmentId: 1, Name: "Pitched Roof Window Buying Guide", Url: "buying-guide-pitched", TagId: 15"}
{InfoPageId: 8, DepartmentId: 1, Name: "Pitched Roof Window Buying Guide", Url: "buying-guide-pitched", TagId: 12"}
]
但是,您可以看到 TagId 是不同的。
我希望能够遍历我的“infos”数组,并且只将对象添加到我的“filteredResults”数组中,但也只在“Tagids”数组中存在具有相同“InfoPageId”的每个对象的 TagId 时添加该对象. 例如,如果“InfoPageId”为 8 的对象的 TagId 为 12 和 15,并且“TagIds”数组的值为 12 和 15,则将对象添加到“filteredResults”数组中,但如果对象仅包含12 但“TagIds”数组的值 12 和 15 不相加。
所需输出的示例;
输入:
TagIds = [10, 5]
infos = [
{InfoPageId: 11, DepartmentId: 1, Name: "Flat Roof Window Buying Guide", Url: "buying-guide-rooflights", Tagid: 10"}
{InfoPageId: 11, DepartmentId: 1, Name: "Flat Roof Window Buying Guide", Url: "buying-guide-rooflights", Tagid: 5"}
{InfoPageId: 12, DepartmentId: 1, Name: "Flat Roof Window Buying Guide", Url: "buying-guide-rooflights", Tagid: 10"}
]
输出:
filteredResults = [
{InfoPageId: 11, DepartmentId: 1, Name: "Flat Roof Window Buying Guide", Url: "buying-guide-rooflights", Tagid: 10"}
]
希望你们能明白这一点。它很难解释。
解决方案
试试这个:
getFiltered(infos: any) {
// reduces every row to a pair containing InfoPageId: [all TagIds]
let reduced = infos.reduce((acc, v) =>
(acc[v.InfoPageId] = [...acc[v.InfoPageId] || [], v.TagId], acc), {}
);
// finds all pageIds that match every existing TagId
let fullTagMatchedIds = Object.keys(reduced).filter(
key => this.TagIds.reduce((acc, tag) => acc && reduced[key].includes(tag), true)
);
// retrieves first row of each pageId that matched all TagIds
let filteredResults = fullTagMatchedIds
.map(infoId => infos.find(info => info.InfoPageId == infoId));
this.infos = filteredResults;
}
请参阅StackBlitz。
请注意,输出仅显示一个标签,因为这就是您编写输出示例的方式(它仅输出包含给定 的第一行PageInfoId
)。如果您希望过滤后的对象包含所有match TagIds
,我将不得不对其进行一些更改。
我将它们保持原样,但我强烈建议您重命名变量以符合OOP 命名约定- 不要以 PascalCase 命名变量(以大写开头),因为该样式是为类保留的。更喜欢使用较低的驼峰命名法作为属性。
推荐阅读
- javascript - 如何在 vue js 中的表单中使用模板
- vhdl - 在modelsim的VHDL测试平台中未检测到endfile,测试平台只是不断重复它自己不确定
- bash - 文件之间的暂停一个一个地复制文件
- image - 无法从 registry.redhat.io 中提取 Red Hat Linux 的 JBoss EAP 7.2 的 Docker 映像
- c# - 在主函数中找不到 appsettings.json 文件?
- javascript - 类型错误:currentTodos.map 不是函数
- php - 作曲家试图分配所有 ram pc
- java - 当rest模板有使用Spring boot 1.5.x的拦截器时,我们可以使用@RestClientTest吗?
- c++ - 在控制台中打印出字符的问题
- c++ - Q_INVOKABLE const getter 返回 undefined,non-const getter 返回正确值 - 为什么?