You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native如何实现忽略数组顺序的两个对象相等性校验

React Native 忽略数组元素顺序的对象相等校验方案

你目前使用JSON.stringify对比的问题在于,该方法序列化时会严格遵循数组元素顺序、对象键的输出顺序,只要顺序有差异,序列化结果就会不同,无法满足你的需求。下面提供两种可直接落地的实现方案:

方案1:基于Lodash自定义比较(推荐,边界场景兼容完善)

Lodash的isEqualWith方法支持自定义比较规则,我们可以针对数组类型做忽略顺序的特殊处理:

  1. 依赖安装(如果项目未引入Lodash,可只安装单包减小体积):
npm install lodash.isequalwith
# 或 yarn add lodash.isequalwith
  1. 比较逻辑实现:
import isEqualWith from 'lodash.isequalwith';

// 可根据业务场景修改数组元素唯一标识的字段名
const ARRAY_ITEM_UNIQUE_KEY = 'addon_id';

const customCompare = (val1, val2) => {
  // 仅对数组做忽略顺序的特殊处理
  if (Array.isArray(val1) && Array.isArray(val2)) {
    // 数组长度不等直接判定不相等
    if (val1.length !== val2.length) return false;
    // 将第二个数组转为 唯一标识->元素 的映射表
    const val2Map = new Map(val2.map(item => [item[ARRAY_ITEM_UNIQUE_KEY], item]));
    // 遍历第一个数组,逐一匹配元素并深度比较
    return val1.every(item => {
      const matchItem = val2Map.get(item[ARRAY_ITEM_UNIQUE_KEY]);
      return matchItem ? isEqualWith(item, matchItem, customCompare) : false;
    })
  }
  // 非数组类型走默认深度比较逻辑
  return undefined;
}

// 调用示例
const isObjEqual = isEqualWith(obj1, obj2, customCompare);
console.log(isObjEqual); // 输出 true

方案2:自研轻量比较函数(无第三方依赖)

如果不想引入外部依赖,可直接使用以下轻量实现,适配常规业务场景:

/**
 * 深度比较两个值是否相等,数组忽略元素顺序
 * @param {*} a 比较值1
 * @param {*} b 比较值2
 * @param {string} arrayItemUniqueKey 数组对象元素的唯一标识字段
 * @returns {boolean} 是否相等
 */
const deepEqualIgnoreArrayOrder = (a, b, arrayItemUniqueKey = 'addon_id') => {
  // 基础类型/引用地址相等直接返回true
  if (a === b) return true;
  // 空值/类型不同直接返回false
  if (a == null || b == null || typeof a !== typeof b) return false;
  // 数组比较逻辑
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    const bMap = new Map(b.map(item => [
      typeof item === 'object' && item !== null ? item[arrayItemUniqueKey] : item,
      item
    ]));
    return a.every(item => {
      const key = typeof item === 'object' && item !== null ? item[arrayItemUniqueKey] : item;
      const match = bMap.get(key);
      return match ? deepEqualIgnoreArrayOrder(item, match, arrayItemUniqueKey) : false;
    })
  }
  // 对象比较逻辑
  if (typeof a === 'object') {
    const aKeys = Object.keys(a);
    const bKeys = Object.keys(b);
    if (aKeys.length !== bKeys.length) return false;
    return aKeys.every(key => bKeys.includes(key) && deepEqualIgnoreArrayOrder(a[key], b[key], arrayItemUniqueKey))
  }
  return false;
}

// 调用示例
console.log(deepEqualIgnoreArrayOrder(obj1, obj2)); // 输出 true

注意事项

  • 如果数组内元素为基础类型(数字、字符串等),上述逻辑会自动把元素本身作为唯一标识匹配,无需额外修改
  • 如果比较的对象存在循环引用,需要额外增加缓存逻辑避免栈溢出,普通业务场景无需处理

内容的提问来源于stack exchange,提问作者carch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 10:54:03