Với Jasmine có cách nào để kiểm tra xem 2 mảng có chứa các phần tử giống nhau nhưng không nhất thiết phải cùng thứ tự không? I E
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
Với Jasmine có cách nào để kiểm tra xem 2 mảng có chứa các phần tử giống nhau nhưng không nhất thiết phải cùng thứ tự không? I E
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
Câu trả lời:
Nếu đó chỉ là số nguyên hoặc các giá trị nguyên thủy khác, bạn có thể sort()
so sánh chúng trước khi so sánh.
expect(array1.sort()).toEqual(array2.sort());
Nếu các đối tượng của nó, hãy kết hợp nó với map()
hàm để trích xuất một số nhận dạng sẽ được so sánh
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());
"10" < "2" === true
[10, 2, 1].sort() ---> [1, 10, 2]
sort
xảy ra tại chỗ. (nó thay đổi phiên bản mà nó được gọi)
sort
sử dụng một chức năng tùy chọn mà nó có thể sử dụng để so sánh.
jasmine phiên bản 2.8 trở lên có
jasmine.arrayWithExactContents()
Dự kiến rằng một mảng chứa chính xác các phần tử được liệt kê, theo bất kỳ thứ tự nào.
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(array2))
đơn giản...
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayContaining(array2));
// 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)
.forEach
thay vì .map
để tiết kiệm thời gian và bộ nhớ.
array1 = [1, 2]
,array2 = [1, 1]
[1,1,2]
và [1,2,2]
? Có thể sử dụng Bản đồ cho từng cái hay cái gì đó? ví dụ array1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())
cho cả hai mảng, sau đó lặp qua chúng và kiểm tra xem số lượng có giống nhau không? Có vẻ như rất nhiều lần lặp lại nhưng sẽ kỹ lưỡng hơn.
Bạn có thể sử dụngpect.arrayContaining (mảng) từ jest tiêu chuẩn:
const expected = ['Alice', 'Bob'];
it('matches even if received contains additional elements', () => {
expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
});
Gói jest mở rộng cung cấp cho chúng tôi một số xác nhận để đơn giản hóa các thử nghiệm của chúng tôi, nó ít dài dòng hơn và đối với các thử nghiệm không thành công, lỗi rõ ràng hơn.
Đối với trường hợp này, chúng tôi có thể sử dụng toIncludeSameMembers
expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
//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;
}
function equal(arr1, arr2){
return arr1.length === arr2.length
&&
arr1.every((item)=>{
return arr2.indexOf(item) >-1
})
&&
arr2.every((item)=>{
return arr1.indexOf(item) >-1
})
}
Ý tưởng ở đây là trước tiên xác định xem độ dài của hai mảng có bằng nhau hay không, sau đó kiểm tra xem tất cả các phần tử có nằm trong mảng của mảng kia hay không.
equal([1, 1, 2], [1, 2, 2])
trả lại true
.
Đây là một giải pháp sẽ hoạt động cho bất kỳ số hoặc mảng nào
https://gist.github.com/tvler/cc5b2a3f01543e1658b25ca567c078e4
const areUnsortedArraysEqual = (...arrs) =>
arrs.every((arr, i, [first]) => !i || arr.length === first.length) &&
arrs
.map(arr =>
arr.reduce(
(map, item) => map.set(item, (map.get(item) || 0) + 1),
new Map(),
),
)
.every(
(map, i, [first]) =>
!i ||
[...first, ...map].every(([item]) => first.get(item) === map.get(item)),
);
Một số bài kiểm tra (một số câu trả lời cho câu hỏi này không tính đến mảng có nhiều mục có cùng giá trị, vì vậy [1, 2, 2] và [1, 2] sẽ trả về true không chính xác)
[1, 2] true
[1, 2], [1, 2] true
[1, 2], [1, 2], [1, 2] true
[1, 2], [2, 1] true
[1, 1, 2], [1, 2, 1] true
[1, 2], [1, 2, 3] false
[1, 2, 3, 4], [1, 2, 3], [1, 2] false
[1, 2, 2], [1, 2] false
[1, 1, 2], [1, 2, 2] false
[1, 2, 3], [1, 2], [1, 2, 3] false
Thuật toán này rất tốt cho các mảng mà mỗi mục là duy nhất. Nếu không, bạn có thể thêm một cái gì đó vào để kiểm tra các bản sao ...
tests = [
[ [1,0,1] , [0,1,1] ],
[ [1,0,1] , [0,0,1] ], //breaks on this one...
[ [2,3,3] , [2,2,3] ], //breaks on this one also...
[ [1,2,3] , [2,1,3] ],
[ [2,3,1] , [1,2,2] ],
[ [2,2,1] , [1,3,2] ]
]
tests.forEach(function(test) {
console.log('eqArraySets( '+test[0]+' , '+test[1]+' ) = '+eqArraySets( test[0] , test[1] ));
});
function eqArraySets(a, b) {
if ( a.length !== b.length ) { return false; }
for ( var i = a.length; i--; ) {
if ( !(b.indexOf(a[i])>-1) ) { return false; }
if ( !(a.indexOf(b[i])>-1) ) { return false; }
}
return true;
}
Cách tiếp cận này có hiệu suất thời gian chạy trong trường hợp xấu nhất theo lý thuyết kém hơn, nhưng vì nó không thực hiện bất kỳ lần ghi nào trên mảng, nó có thể nhanh hơn trong nhiều trường hợp (chưa kiểm tra hiệu suất):
CẢNH BÁO: Như Torben đã chỉ ra trong các nhận xét, cách tiếp cận này chỉ hoạt động nếu cả hai mảng đều có các phần tử duy nhất (không lặp lại) (giống như một số câu trả lời khác ở đây).
/**
* Determine whether two arrays contain exactly the same elements, independent of order.
* @see /programming/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>
Array#sort
sắp xếp các mảng tại chỗ.
Hiện tại có một trình so khớp cho TRƯỜNG HỢP SỬ DỤNG này:
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' }]);
});
Bạn có thể sử dụng một cái gì đó như:
expect(array1).toEqual(jasmine.arrayContaining(array2));
Ghi nhớ nhập jasmine
. Hoặc thêm nó vào.eslintrc
Jest có một hàm được gọi expect.arrayContaining
sẽ làm chính xác những gì bạn muốn:
expect(array1).toEqual(expect.arrayContaining(array2))
bạn có thể muốn kiểm tra xem chúng cũng có cùng độ dài hay không, vì bài kiểm tra sẽ vượt qua nếu
mảng mong đợi là một tập hợp con của mảng đã nhận
theo doc.
CHỈNH SỬA: Xin lỗi vì tôi không nhận thấy thẻ hoa nhài, đây là một cách hoạt động với Jest
expect(array1.sort()).toEqual(array2.sort());
?