Gibt es mit Jasmine eine Möglichkeit zu testen, ob 2 Arrays dieselben Elemente enthalten, aber nicht unbedingt in derselben Reihenfolge? dh
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
javascript
jasmine
karma-jasmine
David sagt Reinstate Monica
quelle
quelle
expect(array1.sort()).toEqual(array2.sort());
?Antworten:
Wenn es sich nur um Ganzzahlen oder andere primitive Werte handelt, können Sie
sort()
diese vor dem Vergleich verwenden.Wenn es sich um Objekte handelt, kombinieren Sie es mit der
map()
Funktion, um einen zu vergleichenden Bezeichner zu extrahierenarray1 = [{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());
quelle
"10" < "2" === true
[10, 2, 1].sort() ---> [1, 10, 2]
sort
dies an Ort und Stelle geschieht. (es mutiert die Instanz, auf der es aufgerufen wird)sort
eine optionale Funktion, mit der der Vergleich durchgeführt werden kann.Jasmin Version 2.8 und höher hat
Was erwartet, dass ein Array genau die aufgelisteten Elemente in beliebiger Reihenfolge enthält.
array1 = [1,2,3]; array2 = [3,2,1]; expect(array1).toEqual(jasmine.arrayWithExactContents(array2))
Siehe https://jasmine.github.io/api/3.4/jasmine.html
quelle
einfach...
array1 = [1,2,3]; array2 = [3,2,1]; expect(array1).toEqual(jasmine.arrayContaining(array2));
quelle
// 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)
quelle
.forEach
stattdessen.map
, um Zeit und Speicherplatz zu sparen.array1 = [1, 2]
,array2 = [1, 1]
[1,1,2]
und sind[1,2,2]
? Vielleicht eine Karte für jede oder etwas? zBarray1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())
für beide Arrays, dann durchlaufen Sie sie und überprüfen Sie, ob die Beträge gleich sind? Scheint wie viele Iterationen, wäre aber gründlicher.Sie könnten expected.arrayContaining (Array) aus Standard-Scherz verwenden:
const expected = ['Alice', 'Bob']; it('matches even if received contains additional elements', () => { expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected)); });
quelle
Das Jest-Extended- Paket enthält nur wenige Aussagen zur Vereinfachung unserer Tests. Es ist weniger ausführlich und bei fehlgeschlagenen Tests ist der Fehler expliziter.
In diesem Fall könnten wir toIncludeSameMembers verwenden
expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
quelle
//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; }
quelle
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 }) }
Die Idee hier ist, zuerst festzustellen, ob die Länge der beiden Arrays gleich ist, und dann zu überprüfen, ob sich alle Elemente im Array des anderen befinden.
quelle
equal([1, 1, 2], [1, 2, 2])
Rücksendungentrue
.Hier ist eine Lösung, die für eine beliebige Anzahl oder Arrays funktioniert
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)), );
Einige Tests (einige Antworten auf diese Frage berücksichtigen keine Arrays mit mehreren Elementen desselben Werts, sodass [1, 2, 2] und [1, 2] fälschlicherweise true zurückgeben würden)
[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
quelle
Dieser Algorithmus eignet sich hervorragend für Arrays, bei denen jedes Element ein Unikat ist. Wenn nicht, können Sie etwas hinzufügen, um nach Duplikaten zu suchen ...
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; }
quelle
Dieser Ansatz weist eine schlechtere theoretische Worst-Case-Laufzeitleistung auf. Da jedoch keine Schreibvorgänge auf dem Array ausgeführt werden, ist er unter vielen Umständen möglicherweise schneller (die Leistung wurde noch nicht getestet):
WARNUNG: Wie Torben in den Kommentaren hervorhob, funktioniert dieser Ansatz nur, wenn beide Arrays eindeutige (sich nicht wiederholende) Elemente haben (genau wie einige der anderen Antworten hier).
/** * 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>
quelle
Array#sort
sortiert Arrays an Ort und Stelle.Derzeit gibt es einen Matcher für diesen USE CASE:
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' }]); });
quelle
Sie könnten etwas verwenden wie:
expect(array1).toEqual(jasmine.arrayContaining(array2));
Denken Sie daran, importieren
jasmine
. Oder fügen Sie es Ihrem hinzu.eslintrc
quelle
Jest hat eine Funktion namens,
expect.arrayContaining
die genau das tut, was Sie wollen:Möglicherweise möchten Sie auch überprüfen, ob sie dieselbe Länge haben, da der Test bestanden wird, wenn
nach dem doc.
EDIT: Tut mir leid, dass ich das Jasmin-Tag nicht bemerkt habe. Dies ist eine Methode, die mit Jest funktioniert
quelle