如何在TypeScript/JavaScript中找出JSON对象数组的组名差异
找出两个JSON对象数组中属性值有差异的group_name
需求:对比两个结构一致的对象数组,定位哪些group_name对应的对象存在属性值差异,最终获取这些组名。
解决方案
实现思路
- 将两个数组转换为以
group_name为键的映射对象,快速定位对应组的数据; - 收集所有出现过的
group_name,避免遗漏仅在单个数组中存在的组; - 逐个对比每组的属性值(排除
group_name本身),判断是否存在差异; - 汇总所有有差异的组名并输出结果。
代码实现
基础版本(JSON.stringify深对比)
适合数组顺序固定、结构简单的场景:
ngOnInit() { // 转换为group_name为键的映射 const groupMap1 = this.jsonobj1.reduce((acc, item) => { acc[item.group_name] = item; return acc; }, {} as Record<string, typeof this.jsonobj1[0]>); const groupMap2 = this.jsonobj2.reduce((acc, item) => { acc[item.group_name] = item; return acc; }, {} as Record<string, typeof this.jsonobj2[0]>); // 获取所有存在的组名 const allGroupNames = new Set([...Object.keys(groupMap1), ...Object.keys(groupMap2)]); const differentGroups: string[] = []; for (const name of allGroupNames) { const item1 = groupMap1[name]; const item2 = groupMap2[name]; // 处理仅在一个数组中存在的组 if (!item1 || !item2) { differentGroups.push(name); continue; } // 排除group_name后对比属性 const compareObj1 = {...item1}; delete compareObj1.group_name; const compareObj2 = {...item2}; delete compareObj2.group_name; if (JSON.stringify(compareObj1) !== JSON.stringify(compareObj2)) { differentGroups.push(name); } } if (differentGroups.length === 0) { console.log('两个数组完全相同'); } else { console.log(`存在差异的组:${differentGroups.join(', ')}`); differentGroups.forEach(name => { console.log(`组 ${name} 的属性值存在差异`); }); } }
增强版本(自定义深对比函数)
如果需要忽略数组元素顺序、处理复杂嵌套结构,可使用自定义深对比逻辑:
// 自定义深对比函数 function isDeepEqual(a: any, b: any): boolean { // 基本类型直接对比 if (a === b) return true; // 数组对比(若需忽略顺序,可先排序再对比) if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (!isDeepEqual(a[i], b[i])) return false; } return true; } // 对象对比 if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) { const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; for (const key of keysA) { if (!keysB.includes(key) || !isDeepEqual(a[key], b[key])) return false; } return true; } return false; } ngOnInit() { const groupMap1 = this.jsonobj1.reduce((acc, item) => { acc[item.group_name] = item; return acc; }, {} as Record<string, typeof this.jsonobj1[0]>); const groupMap2 = this.jsonobj2.reduce((acc, item) => { acc[item.group_name] = item; return acc; }, {} as Record<string, typeof this.jsonobj2[0]>); const allGroupNames = new Set([...Object.keys(groupMap1), ...Object.keys(groupMap2)]); const differentGroups: string[] = []; for (const name of allGroupNames) { const item1 = groupMap1[name]; const item2 = groupMap2[name]; if (!item1 || !item2) { differentGroups.push(name); continue; } const compareObj1 = {...item1}; delete compareObj1.group_name; const compareObj2 = {...item2}; delete compareObj2.group_name; if (!isDeepEqual(compareObj1, compareObj2)) { differentGroups.push(name); } } if (differentGroups.length === 0) { console.log('两个数组完全相同'); } else { console.log(`存在差异的组:${differentGroups.join(', ')}`); differentGroups.forEach(name => { console.log(`组 ${name} 的属性值存在差异`); }); } }
说明
- 映射转换避免了嵌套循环,提升了对比效率;
- 同时处理了仅在单个数组中存在的组,确保结果全面;
- 自定义深对比函数可根据需求调整逻辑(比如是否忽略数组顺序)。
内容的提问来源于stack exchange,提问作者EMahan K
相关产品推荐
相关产品推荐

