import { getType } from "../getType/getType"; /** * 深度比较两个对象或数组,返回是否相等或不一致的 key * @param {Object|Array} obj1 - 第一个对象/数组 * @param {Object|Array} obj2 - 第二个对象/数组 * @param {Object} options - 配置项 * @param {boolean} options.returnKeys - 是否返回不一致的 key(默认 false) * @param {boolean} options.arrayDiff - 是否检查数组内差异(默认 true) * @returns {boolean | string[]} - 相等返回 false,不相等返回 true 或不同 key * * @see {@link https://yourhhh.github.io/zztoolDocument} API 文档 * @example * ```javascript * // 调用示例 * const obj1 = { a: 1, b: { c: 2 } }; * const obj2 = { a: 1, b: { c: 3 } }; * console.log(equal(obj1, obj2, { returnKeys: true })); // ['b.c'] * ``` */ export function equal( obj1: any, obj2: any, options: { returnKeys: true; arrayDiff?: boolean } ): string[]; export function equal( obj1: any, obj2: any, options?: { returnKeys?: false; arrayDiff?: boolean } ): boolean; export function equal( obj1: any, obj2: any, options: { returnKeys?: boolean; arrayDiff?: boolean } = {} ):boolean | string[] { const defaultOptions = { returnKeys: false, arrayDiff: true }; const { returnKeys, arrayDiff } = { ...defaultOptions, ...options }; // function isObject(value: any) { // return value && typeof value === "object" && !Array.isArray(value); // } function compareRecursive(obj1: any, obj2: any, parentKey = ""): Array { if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) { throw new Error("Both arguments must be objects or arrays."); } const differingKeys: Array = []; const keys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]); keys.forEach((key) => { const fullKey = parentKey ? `${parentKey}.${key}` : key; const val1 = obj1[key]; const val2 = obj2[key]; if (getType(val1) === 'object' && getType(val2) === 'object') { differingKeys.push(...compareRecursive(val1, val2, fullKey)); } else if (Array.isArray(val1) && Array.isArray(val2)) { if (arrayDiff) { const maxLength = Math.max(val1.length, val2.length); for (let i = 0; i < maxLength; i++) { const v1 = val1[i]; const v2 = val2[i]; const arrKey = `${fullKey}.${i}`; if (getType(v1) === 'object' && getType(v2) === 'object') { differingKeys.push(...compareRecursive(v1, v2, arrKey)); } else if (v1 !== v2) { differingKeys.push(arrKey); } } } } else if (val1 !== val2) { differingKeys.push(fullKey); } }); return differingKeys; } const result = compareRecursive(obj1, obj2); return returnKeys ? result : result.length > 0; }