使用 Chai 查看两个对象是否相同,其中一个属性具有不同的顺序

See if two objects are the same where one attribute has a different order using Chai

提问人:webdesignnoob 提问时间:7/8/2022 最后编辑:M. Justinwebdesignnoob 更新时间:11/15/2023 访问量:702

问:

我有两个对象数组:

array1 = [ 
  { name: 'Kitty, Hello',
    otherNames: [ '(1) One', '(2) Two' ] 
  },
  { name: 'Cat, Garfield',
    otherNames: [ '(3) Three' ] 
  } 
];

array2 = [ 
  { name: 'Kitty, Hello',
    otherNames: [ '(2) Two', '(1) One' ] 
  },
  { name: 'Cat, Garfield', 
    otherNames: [ '(3) Three' ] 
   } 
]

我正在尝试使用 Chai 来查看它们是否相等,尽管在 'array2 中处于不同的顺序。otherNamesarray1

我试过:

array1.to.be.eql(array2) //false
array1.to.have.deep.members(array2) //false

但它不断返回 false。这甚至可能吗?我试过看类似的问题,但我只能找到“name”和“otherNames”顺序不同的问题。

JavaScript 平等

评论


答:

1赞 Cristian-Florin Calina 7/8/2022 #1

好吧,它们不相等,因为它们在数组中具有不同的值。您可以对数组进行排序并检查它们是否相等。

const getSortedAtKey = (array, key = 'otherNames') => {
  return array.map(value => ({
    ...value,
    [key]: value[key].sort()
  }));
}

expect(getSortedAtKey(array1)).to.eql(getSortedAtKey(array2))

这个函数很好,因为你可以为多个属性链接它(例如,如果你有要验证的数组,你可以调用otherNamesotherAgesgetSortedAtKey(getSortedAtKey(array1), 'otherAges')

评论

0赞 webdesignnoob 7/8/2022
我明白了,我以为我可以做一些事情,说它包含在对象中,只是顺序不正确。排序解决了我的问题。非常感谢!
0赞 HEllRZA 7/8/2022 #2

有一个包。https://www.npmjs.com/package/deep-equal-in-any-order

const deepEqualInAnyOrder = require('deep-equal-in-any-order');
const chai = require('chai');

chai.use(deepEqualInAnyOrder);

const { expect } = chai;

expect(array1).to.deep.equalInAnyOrder(array2);
0赞 user22912780 11/15/2023 #3

如果最初的帖子是最近的,我建议@webdesignnoob重新考虑他的设计。从广义上讲,这个问题与对象之间的等价概念有关。

在 @ut8pia/分类器库中,等价可以通过表示函数实现:

const 
  objRepr = obj => [obj.name, ...obj.otherNames.sort()],
  arrayRepr = array => array.map(objRepr).flat().join(', '),
  
  equal = TrueSet.of(arrayRepr, ORDER.ASCENDING, ORDER.SINGULAR)
    .let(array1)
      .has(array2)

该库声称可以解决 JavaScript 中对排序集合的长期需求。有关详细说明,请参阅在线文档