
本文介绍如何在 angular 应用中高效比较两个结构不一致的对象数组,依据 `uniqueid` 或 `userid/id` 等关键字段识别并移除主数组中与第二数组存在逻辑重复的项,返回精简后的纯净数据集。
在 Angular(或通用 TypeScript)开发中,常需对来源不同、结构不一的数组进行逻辑去重——例如从后端获取的主数据列表(含丰富嵌套字段)需剔除已被另一配置列表标记为“已禁用”或“待移除”的条目。本例中,mainArray 包含多个复杂对象(含 uniqueId、userId、嵌套 source 和 headers),而 secondArray 是扁平化管理对象(含 UniqueId、Id、Enable 等字段),二者无直接类型对应,但存在业务层面的关联关系:若 mainArray 中某对象的 uniqueId 与 secondArray 中任一对象的 UniqueId 相同,或其 userId 与 secondArray 中某对象的 Id 相同,则该主对象应被过滤掉。
以下是一个健壮、可复用的 TypeScript 工具函数实现:
function filterOutDuplicates(
mainArray: any[],
secondArray: any[]
): any[] {
return mainArray.filter((item) => {
// 跳过空/无效项
if (!item) return false;
// 条件1:检查 uniqueId 是否存在于 secondArray.UniqueId 中
const hasMatchingUniqueId = item.uniqueId &&
secondArray.some(secondItem =>
secondItem.UniqueId === item.uniqueId
);
// 条件2:检查 userId 是否存在于 secondArray.Id 中(注意字段名大小写差异)
const hasMatchingUserId = item.userId &&
secondArray.some(secondItem =>
secondItem.Id === item.userId
);
// 仅当两项均不匹配时保留该主对象(即:无重复才保留)
return !(hasMatchingUniqueId || hasMatchingUserId);
});
}✅ 使用示例:
const mainData = [
{ "userId": 8, "name": "Adfgh", "uniqueId": "rthj", /* ... */ },
{ "userId": 8, "name": "FGHJKNJKN", "uniqueId": "etjhjub", /* ... */ },
{ "customerId": 8, "name": "name", "uniqueId": "remove", /* ... */ },
// ... 其他项
];
const configData = [
{ "Id": 98, "UniqueId": "remove", "Enable": false },
{ "Id": 154, "UniqueId": "NEO-TEST", "Enable": false }
];
const cleanedData = filterOutDuplicates(mainData, configData);
console.log(cleanedData); // 输出不含 uniqueId === "remove" 的三项⚠️ 关键注意事项:
- 字段名大小写敏感:secondArray 中为 UniqueId 和 Id(首字母大写),而 mainArray 中为 uniqueId 和 userId(小驼峰)。代码中已显式处理,切勿直接使用 === 比较未标准化的键名。
- 空值防御:函数主动跳过 null / undefined 的 item,避免运行时错误;同时对 item.uniqueId 和 item.userId 做真值判断,防止 0、"" 等 falsy 值误判。
-
性能考量:对中等规模数组( 索引:
const uniqueIdSet = new Set(secondArray.map(i => i.UniqueId)); const idSet = new Set(secondArray.map(i => i.Id)); // 后续用 uniqueIdSet.has(item.uniqueId) 替代 some(),时间复杂度从 O(n²) 降至 O(n)
- Angular 环境集成:可将此函数封装为独立工具服务(如 DataFilterService),或作为纯函数置于 utils/ 目录下,在组件或 Effect 中按需调用,保持逻辑解耦。
总结而言,该方案不依赖外部库(如 Lodash),完全基于原生 JavaScript/TypeScript 方法,语义清晰、易于测试与维护,精准满足跨结构数组的业务级去重需求——核心在于明确“什么是重复”,而非追求字面 JSON 相等。










