如何比较含多层嵌套数组的对象且忽略数组内元素顺序
嵌套对象忽略数组顺序的深度相等比较实现
核心实现函数
你可以直接使用下面的原生JS函数,无需引入第三方依赖:
function deepEqualIgnoreArrayOrder(a, b) { // 基础类型直接全等判断 if (a === b) return true; // 非对象/Null直接返回不相等 if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) { return false; } // 处理数组场景 if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; // 复制第二个数组避免修改原数据,用于匹配后移除元素 const bCopy = [...b]; for (const itemA of a) { let matchedIndex = -1; // 遍历剩余未匹配的b元素 for (let i = 0; i < bCopy.length; i++) { if (deepEqualIgnoreArrayOrder(itemA, bCopy[i])) { matchedIndex = i; break; } } if (matchedIndex === -1) return false; // 匹配成功则移除该元素,避免重复匹配 bCopy.splice(matchedIndex, 1); } return true; } // 处理普通对象场景 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) || !deepEqualIgnoreArrayOrder(a[key], b[key])) { return false; } } return true; }
功能说明
- 支持任意层级的嵌套对象、嵌套数组比较
- 所有数组的元素顺序都会被忽略,仅校验元素内容是否完全匹配
- 基础类型、引用类型的判断符合常规深度相等逻辑
- 不会修改传入的原对象和数组
使用示例
你给出的两个测试场景都可以直接使用该函数校验:
// 示例1调用 console.log(deepEqualIgnoreArrayOrder(object1, object2)) // 输出true // 示例2调用 console.log(deepEqualIgnoreArrayOrder(object1, object2)) // 输出true
如果是在单元测试场景下使用,你可以基于该函数封装自定义断言,比如Chai的自定义断言写法:
chai.Assertion.addMethod('fundamentallyEqual', function (expected) { this.assert( deepEqualIgnoreArrayOrder(this._obj, expected), 'expected #{this} to be fundamentally equal ignoring array order', 'expected #{this} to not be fundamentally equal ignoring array order', expected ); }); // 调用方式和你示例的写法一致 expect(object1).to.be.fundamentallyEqual(object2);
内容的提问来源于stack exchange,提问作者Cavarica2
相关产品推荐
相关产品推荐

