首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >比较两个对象数组是否相等,而不管对象属性的顺序如何

比较两个对象数组是否相等,而不管对象属性的顺序如何
EN

Stack Overflow用户
提问于 2022-05-05 15:48:23
回答 1查看 1.4K关注 0票数 1

我试图比较两个对象数组是否相等,而忽略了属性顺序上的任何差异。我只想知道每个属性的值何时匹配。下面是根据每个属性值对每个数组中的一个对象进行比较的示例,这些对象应该相等。属性的排序与“值”属性值的排序无关。

{ "fieldId":"123456789",

"operationType":1

"definitionType":1

“价值”:"123","456",

"isAllSelected":假,

"dateRangeSelectionType":0

{ "isAllSelected":false,

"operationType":1

"definitionType":1

"fieldId":"123456789“

“价值”:"456","123",

"dateRangeSelectionType":0

}

我尝试过使用JSON.stringify来比较这些数组,但我知道这是行不通的,因为它会考虑到排序是否相等。

我还为另一个对象数组使用了以下助手函数,但是这些函数对这些数组没有正常工作:

代码语言:javascript
运行
复制
> const objectsAreEqual = (object1: any, object2: any) =>
>     Object.keys(object1).length === Object.keys(object2).length 
>     && Object.keys(object1).every(index => object1[index] === object2[index]);
> 
> const objectArraysAreEqual = (array1: Object[], array2: Object[]) =>
>     array1.length === array2.length && array1.every((x, index) => objectsAreEqual(x, array2[index]));
EN

回答 1

Stack Overflow用户

发布于 2022-05-05 16:32:55

首先,请注意,我稍微清理了一下数据。在第二个示例对象中,"isAllSelected": false,出现了两次,这不是一个有效的javascript对象。另外,值数组有其元素交换的顺序,这使得这些元素实际上不是同一个对象,因此对于这些演示示例,我将它们作为完全相同的数组。

因为您将此标记为TypeScript问题,所以我首先为这个对象形状创建了一个TypeScript类型,我将其命名为"Foo“。

代码语言:javascript
运行
复制
type Foo = {
  fieldId: string;
  operationType: number;
  definitionType: number;
  values: string[];
  isAllSelected: boolean,
  dateRangeSelectionType: number
}

然后我将这两个对象定义为Foo类型。

代码语言:javascript
运行
复制
const fooA: Foo = { 
  "fieldId": "123456789",
  "operationType": 1,
  "definitionType": 1,
  "values": ["123","456"],
  "isAllSelected": false,
  "dateRangeSelectionType": 0
}

const fooB: Foo = { 
  "isAllSelected": false,
  "operationType": 1,
  "definitionType": 1,
  "fieldId": "123456789",
  "values": ["123", "456"],
  "dateRangeSelectionType": 0
}

使用==和===运算符对基本类型很好,但是它们在比较这些对象时会返回"false“,"Object.is”函数也是如此。

代码语言:javascript
运行
复制
console.log(fooA == fooB)               // false    
console.log(fooA === fooB)              // false
console.log(Object.is(fooA, fooB))      // false

所以,看起来你得卷起袖子,检查所有的钥匙和物品的价值.

你基本上想做的是:

  1. 确保对象具有相同的键。

  1. 确保这些键具有相同的值。

棘手的部分是,如果值本身是对象,会发生什么?在某些情况下,你可能希望它只是一个浅薄的等价物(例如。如果您希望函数表示它们是相等的,即使“值”数组有不同的元素)。

如果希望函数继续向下钻取并检查对象中的所有内容是否相同,则需要检查“深度相等”。

以下是如何实现此功能的一个实现:

代码语言:javascript
运行
复制
export default function deepEquals(object1: any, object2: any) {
  const keys1 = Object.keys(object1);
  const keys2 = Object.keys(object2);
  if (keys1.length !== keys2.length) {
    return false;
  }
  for (const key of keys1) {
    const val1 = object1[key];
    const val2 = object2[key];
    const areObjects = isObject(val1) && isObject(val2);
    if (
      areObjects && !deepEquals(val1, val2) ||
      !areObjects && val1 !== val2
    ) {
      return false;
    }
  }
  return true;
}

function isObject(object: Object) {
  return object != null && typeof object === 'object';
}

注意,在比较对象时,此函数是如何返回true的:

代码语言:javascript
运行
复制
import deepEquals from './deepEquals';

console.log(deepEquals(fooA, fooB))     // true

您还可以使用具有深度对象比较的库(如has ):

代码语言:javascript
运行
复制
import isEqual from 'lodash.isequal';

console.log(isEqual(fooA, fooB))        // true
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72130068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档