Com o Jasmine, há uma maneira de testar se 2 arrays contêm os mesmos elementos, mas não estão necessariamente na mesma ordem? ie
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
javascript
jasmine
karma-jasmine
David diz Reintegrar Monica
fonte
fonte
expect(array1.sort()).toEqual(array2.sort());
?Respostas:
Se forem apenas números inteiros ou outros valores primitivos, você pode
sort()
colocá-los antes de comparar.Se forem objetos, combine-o com a
map()
função para extrair um identificador que será comparadoarray1 = [{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());
fonte
"10" < "2" === true
[10, 2, 1].sort() ---> [1, 10, 2]
sort
acontece no local, no entanto. (muda a instância na qual é chamado)sort
tem uma função opcional que pode usar para fazer a comparação.jasmine versão 2.8 e posterior tem
Que espera que uma matriz contenha exatamente os elementos listados, em qualquer ordem.
array1 = [1,2,3]; array2 = [3,2,1]; expect(array1).toEqual(jasmine.arrayWithExactContents(array2))
Veja https://jasmine.github.io/api/3.4/jasmine.html
fonte
simples...
array1 = [1,2,3]; array2 = [3,2,1]; expect(array1).toEqual(jasmine.arrayContaining(array2));
fonte
// 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)
fonte
.forEach
vez de.map
para economizar algum tempo e muita memória.array1 = [1, 2]
,array2 = [1, 1]
[1,1,2]
e[1,2,2]
? Talvez usando um mapa para cada um ou algo assim? por exemplo,array1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())
para ambas as matrizes, então faça um loop através delas e verifique se os valores são iguais Parece muitas iterações, mas seria mais completo.Você pode usar expect.arrayContaining (array) do jest padrão:
const expected = ['Alice', 'Bob']; it('matches even if received contains additional elements', () => { expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected)); });
fonte
O pacote jest-extended fornece-nos poucas afirmações para simplificar nossos testes, é menos prolixo e para testes que falham o erro é mais explícito.
Para este caso, poderíamos usar toIncludeSameMembers
expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
fonte
//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; }
fonte
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 }) }
A ideia aqui é primeiro determinar se o comprimento das duas matrizes é o mesmo e, em seguida, verificar se todos os elementos estão na outra matriz.
fonte
equal([1, 1, 2], [1, 2, 2])
devoluçõestrue
.Aqui está uma solução que funcionará para qualquer número ou matrizes
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)), );
Alguns testes (algumas respostas a esta pergunta não levam em consideração matrizes com vários itens do mesmo valor, então [1, 2, 2] e [1, 2] retornariam incorretamente verdadeiro)
[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
fonte
Esse algoritmo é ótimo para matrizes em que cada item é único. Se não, você pode adicionar algo para verificar se há duplicatas ...
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; }
fonte
Esta abordagem tem pior desempenho de tempo de execução teórico de pior caso, mas, como não executa nenhuma gravação na matriz, pode ser mais rápida em muitas circunstâncias (ainda não testei o desempenho):
AVISO: Como Torben apontou nos comentários, essa abordagem só funciona se ambos os arrays tiverem elementos exclusivos (não repetitivos) (assim como várias das outras respostas aqui).
/** * 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>
fonte
Array#sort
classifica matrizes no local.Atualmente existe uma correspondência para este CASO DE USO:
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' }]); });
fonte
jest-extended
, ou seja, não está disponível como uma funcionalidade central do Jest, certo?Você poderia usar algo como:
expect(array1).toEqual(jasmine.arrayContaining(array2));
Lembre-se de importar
jasmine
. Ou adicione ao seu.eslintrc
fonte
Jest tem uma função chamada
expect.arrayContaining
que fará exatamente o que você quiser:você pode querer verificar se eles têm o mesmo comprimento também, uma vez que o teste passará se
de acordo com o doc.
EDIT: Desculpe não ter notado a etiqueta de jasmim, é uma forma que funciona com Jest
fonte