Javascript 期望数组相等而忽略顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32103252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Expect Arrays to be equal ignoring order
提问by David says Reinstate Monica
With Jasmine is there a way to test if 2 arrays contain the same elements, but are not necessarily in the same order? ie
使用 Jasmine 有没有办法测试 2 个数组是否包含相同的元素,但顺序不一定相同?IE
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
回答by Red Panda
If it's just integers or other primitive values, you can sort()
them before comparing.
如果它只是整数或其他原始值,您可以sort()
在比较之前使用它们。
expect(array1.sort()).toEqual(array2.sort());
If its objects, combine it with the map()
function to extract an identifier that will be compared
如果是它的对象,则将其与map()
函数结合以提取将进行比较的标识符
array1 = [{id:1}, {id:2}, {id:3}];
array2 = [{id:3}, {id:2}, {id:1}];
expect(array1.map(a => a.id).sort()).toEqual(array2.map(a => a.id).sort());
回答by keksmasta
jasmine version 2.8 and later has
茉莉花 2.8 及更高版本有
jasmine.arrayWithExactContents()
Which expects that an array contains exactly the elements listed, in any order.
它期望一个数组以任何顺序包含完全列出的元素。
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(array2))
回答by ProfiProg
simple...
简单的...
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayContaining(array2));
回答by Jannic Beck
// check if every element of array2 is element of array1
// to ensure [1, 1] !== [1, 2]
array2.forEach(x => expect(array1).toContain(x))
// check if every element of array1 is element of array2
// to ensure [1, 2] !== [1, 1]
array1.forEach(x => expect(array2).toContain(x))
// check if they have equal length to ensure [1] !== [1, 1]
expect(array1.length).toBe(array2.length)
回答by Ravi
//Compare arrays without order
//Example
//a1 = [1, 2, 3, 4, 5]
//a2 = [3, 2, 1, 5, 4]
//isEqual(a1, a2) -> true
//a1 = [1, 2, 3, 4, 5];
//a2 = [3, 2, 1, 5, 4, 6];
//isEqual(a1, a2) -> false
function isInArray(a, e) {
for ( var i = a.length; i--; ) {
if ( a[i] === e ) return true;
}
return false;
}
function isEqArrays(a1, a2) {
if ( a1.length !== a2.length ) {
return false;
}
for ( var i = a1.length; i--; ) {
if ( !isInArray( a2, a1[i] ) ) {
return false;
}
}
return true;
}
回答by dave008
The jest-extendedpackage provides us few assertions to simplify our tests, it's less verbose and for failing tests the error is more explicit.
该笑话扩展包为我们提供了一些断言以便简化我们的测试中,它的更简洁和失败的测试误差更加明确。
For this case we could use toIncludeSameMembers
对于这种情况,我们可以使用toIncludeSameMembers
expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
回答by Marina
You could use expect.arrayContaining(array) from standard jest:
您可以使用标准玩笑中的 expect.arrayContaining(array) :
const expected = ['Alice', 'Bob'];
it('matches even if received contains additional elements', () => {
expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
});
回答by David Lee
Jest has a function called expect.arrayContaining
which will do exactly what you want:
Jest 有一个被调用的函数expect.arrayContaining
,它可以完全按照您的要求执行操作:
expect(array1).toEqual(expect.arrayContaining(array2))
you may want to check if they are with the same length too, since the test will pass if
您可能还想检查它们是否具有相同的长度,因为如果
the expected array is a subset of the received array
预期数组是接收数组的子集
according to the doc.
根据文档。
回答by Daniel Maldonado
There is currenly a matcher for this USE CASE:
这个用例目前有一个匹配器:
https://github.com/jest-community/jest-extended/pull/122/files
https://github.com/jest-community/jest-extended/pull/122/files
test('passes when arrays match in a different order', () => {
expect([1, 2, 3]).toMatchArray([3, 1, 2]);
expect([{ foo: 'bar' }, { baz: 'qux' }]).toMatchArray([{ baz: 'qux' }, { foo: 'bar' }]);
});
回答by Domi
This approach has worse theoretical worst-case run-time performance, but, because it does not perform any writes on the array, it might be faster in many circumstances (haven't tested performance yet):
这种方法理论上的最坏情况运行时性能较差,但是,由于它不对阵列执行任何写入,因此在许多情况下可能会更快(尚未测试性能):
WARNING: As Torben pointed out in the comments, this approach only works if both arrays have unique (non-repeating) elements (just like several of the other answers here).
警告:正如 Torben 在评论中指出的那样,这种方法仅在两个数组都具有唯一(非重复)元素时才有效(就像这里的其他几个答案一样)。
/**
* Determine whether two arrays contain exactly the same elements, independent of order.
* @see https://stackoverflow.com/questions/32103252/expect-arrays-to-be-equal-ignoring-order/48973444#48973444
*/
function cmpIgnoreOrder(a, b) {
const { every, includes } = _;
return a.length === b.length && every(a, v => includes(b, v));
}
// the following should be all true!
const results = [
!!cmpIgnoreOrder([1,2,3], [3,1,2]),
!!cmpIgnoreOrder([4,1,2,3], [3,4,1,2]),
!!cmpIgnoreOrder([], []),
!cmpIgnoreOrder([1,2,3], [3,4,1,2]),
!cmpIgnoreOrder([1], []),
!cmpIgnoreOrder([1, 3, 4], [3,4,5])
];
console.log('Results: ', results)
console.assert(_.reduce(results, (a, b) => a && b, true), 'Test did not pass!');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>