За допомогою Jasmine чи можна перевірити, чи містять 2 масиви однакові елементи, але не обов’язково в одному порядку? тобто
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
За допомогою Jasmine чи можна перевірити, чи містять 2 масиви однакові елементи, але не обов’язково в одному порядку? тобто
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
Відповіді:
Якщо це лише цілі числа або інші примітивні значення, ви можете sort()
їх перед порівнянням.
expect(array1.sort()).toEqual(array2.sort());
Якщо його об'єкти, об'єднайте його з 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());
"10" < "2" === true
[10, 2, 1].sort() ---> [1, 10, 2]
sort
відбувається на місці. (він змінює екземпляр, за яким його називають)
sort
бере додаткову функцію, яку вона може використовувати для порівняння.
жасмин версії 2.8 та пізнішої версії
jasmine.arrayWithExactContents()
Що очікує, що масив містить точно перераховані елементи в будь-якому порядку.
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(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
замість того, .map
щоб заощадити трохи часу та купу пам’яті.
array1 = [1, 2]
,array2 = [1, 1]
[1,1,2]
і [1,2,2]
? Може, використовувати карту для кожного з них чи щось? наприклад, array1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())
для обох масивів, потім прокрутити їх і перевірити, що суми однакові? Здається, багато повторень, але було б більш ретельно.
Жарт-продовжено надає нам кілька тверджень для спрощення наших тестів, він менш детальний, а для невдалих тестів помилка є більш явною.
У цьому випадку ми можемо використовувати 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
})
}
Ідея тут полягає в тому, щоб спочатку визначити, чи довжина двох масивів однакова, а потім перевірити, чи всі елементи знаходяться в масиві іншого.
equal([1, 1, 2], [1, 2, 2])
повертається true
.
Ось рішення, яке буде працювати для будь-якої кількості чи масивів
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)),
);
Деякі тести (кілька відповідей на це запитання не враховують масиви з кількома елементами однакового значення, тому [1, 2, 2] та [1, 2] неправильно повернуть true)
[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
Цей алгоритм чудово підходить для масивів, де кожен елемент унікальний. Якщо ні, ви можете додати щось, щоб перевірити наявність дублікатів ...
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;
}
Цей підхід має гіршу теоретичну найгіршу продуктивність під час виконання, але, оскільки він не виконує жодних записів на масив, він може бути швидшим за багатьох обставин (ще не перевірив продуктивність):
ПОПЕРЕДЖЕННЯ: Як зазначив Торбен у коментарях, такий підхід працює лише в тому випадку, якщо обидва масиви мають унікальні (не повторювані) елементи (як і деякі інші відповіді тут).
/**
* 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
сортує масиви на місці.
Для цього ВИКОРИСТАНОГО ВИПРАВЛЕННЯ існує збіг:
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' }]);
});
Ви можете використовувати щось на зразок:
expect(array1).toEqual(jasmine.arrayContaining(array2));
Запам’ятайте імпорт jasmine
. Або додайте його до свого.eslintrc
Jest має функцію під назвою, expect.arrayContaining
яка буде робити саме те, що ви хочете:
expect(array1).toEqual(expect.arrayContaining(array2))
Ви можете перевірити, чи мають вони однакову довжину, оскільки тест пройде if
очікуваний масив - це підмножина отриманого масиву
згідно з док.
EDIT: Вибачте, що я не помітив тегу жасмину, це спосіб, який працює з Jest
expect(array1.sort()).toEqual(array2.sort());
?