Expect Arrays to be equal ignoring order
Solution 1
If it's just integers or other primitive values, you can sort()
them before comparing.
expect(array1.sort()).toEqual(array2.sort());
If its objects, combine it with the map()
function to extract an identifier that will be compared
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());
Solution 2
You could use expect.arrayContaining(array) from standard jest:
const expected = ['Alice', 'Bob'];
it('matches even if received contains additional elements', () => {
expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
});
Solution 3
jasmine version 2.8 and later has
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))
See https://jasmine.github.io/api/3.4/jasmine.html
Solution 4
simple...
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayContaining(array2));
Solution 5
The jest-extended package 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
expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
![David says Reinstate Monica](https://i.stack.imgur.com/fGuXb.png?s=256&g=1)
David says Reinstate Monica
https://meta.stackexchange.com/questions/333965/firing-mods-and-forced-relicensing-is-stack-exchange-still-interested-in-cooper?noredirect=1&lq=1 https://meta.stackexchange.com/questions/336024/how-can-we-put-pressure-on-stack-exchange-inc-without-damaging-the-community#comment1110223_336024 https://meta.stackexchange.com/questions/336526/stack-overflow-is-doing-me-ongoing-harm-its-time-to-fix-it Please help in saving StackOverflow!
Updated on July 17, 2021Comments
-
David says Reinstate Monica almost 3 years
With Jasmine is there a way to test if 2 arrays contain the same elements, but are not necessarily in the same order? ie
array1 = [1,2,3]; array2 = [3,2,1]; expect(array1).toEqualIgnoreOrder(array2);//should be true
-
raina77ow almost 9 years
expect(array1.sort()).toEqual(array2.sort());
? -
David says Reinstate Monica almost 9 years@raina77ow I guess that would work as well.
-
raina77ow almost 9 yearsShould I make this an answer?
-
David says Reinstate Monica almost 9 years@raina77ow It gets a little bit more complicated when its an array of objects. It would be nice if Jasmine had something out of the box for this.
-
ktharsis almost 9 yearsI didn't find anything great in jasmine itself so actually introduced lodash (or you could use underscore/other js collection library) into my test project for things just like this.
-
jimmyfever over 3 yearsI like @raina77ow's answer the best. The only caveat is that the
sort
will mutate the input arrays, though that's probably not a big deal. If it causes a problem, you can do[...array1].sort()
-
-
Darkhogg over 6 yearsUse
.forEach
instead of.map
to save some time and a bunch of memory. -
Shmiddty about 6 yearsthe default array sort method uses string comparison for numbers.
"10" < "2" === true
-
Shmiddty about 6 years
[10, 2, 1].sort() ---> [1, 10, 2]
-
Coloured Panda about 6 years@Shmiddty I dont see how it matters in this case. As long as the order is the same for both arrays, it should be fine.
-
Shmiddty about 6 yearsFair point. It is worth noting that
sort
happens in-place, though. (it mutates the instance on which it is called) -
philraj almost 6 yearsWhat do you mean when you say it creates lots of copies?
Array#sort
sorts arrays in-place. -
Torben Kohlmeier over 5 yearsFails for these arrays: [1,1,2,3], [3,3,1,2].
-
Domi over 5 years@TorbenKohlmeier Thanks, I updated my answer (admitting defeat in regard to non-unique arrays)
-
redbmk over 5 years@Shmiddty that's true, but
.map
returns a new array, so you're still not mutating the original. -
redbmk over 5 yearsUnfortunately this will pass with the following arrays even though they are different:
array1 = [1, 2]
,array2 = [1, 1]
-
Jannic Beck over 5 yearsNice catch @redbmk I added a check for this, thanks!
-
redbmk over 5 yearsI think there's still an issue - what if the arrays are
[1,1,2]
and[1,2,2]
? Maybe using a Map for each one or something? e.g.array1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())
for both arrays, then loop through them and check that the amounts are the same? Seems like a lot of iterations but would be more thorough. -
lifecoder over 5 yearsExclusions from the control array may be used (remove element when found, then check length is 0 in the end), but it doesn't worth the effort in regular cases.
-
Kristian Hanekamp over 5 yearsNice answer! You also need to check that the lengths are equal, otherwise you'll have a false positive on [1,2,3,4] and [3,2,1].
-
MarkMYoung over 4 yearsThis does not take into account the frequency of items:
equal([1, 1, 2], [1, 2, 2])
returnstrue
. -
slifty almost 4 yearsThe object portion of this answer will not actually verify that the objects match, since it is only comparing the mapped arrays. You don't need map,
sort
takes an optional function that it can use to do the comparison. -
bluenote10 over 3 yearsBut that is part of
jest-extended
, i.e., not available as a core Jest functionality, right? -
mjarraya over 3 yearsIt is not an appropriate answer for this use case as the two arrays in the question are expected to be equal, with only order differing.
-
Emmanuel Mahuni over 3 yearsthere is
toIncludeSameMembers
injest-extended
. I don't know whether this is equivalent -
enanone about 3 yearsThis is the correct answer. Please mark this as the correct answer. @mjarraya just test for the length of both arrays to be the same and you are fine.
-
mjarraya about 3 yearsIt should not be marked as the correct answer since it is not complete! @enanone
-
zeroliu about 3 yearsThere are two issues: 1. length needs to be checked. expect(actual.length).toEqual(expected.length); 2. It should be jasmine.arrayContaining. jasmine.github.io/2.6/…
-
paul23 almost 3 yearsIf for example the sorting key is "id" but there is extra data and those are not equal (but should be) this fails.
-
Jordan Burnett over 2 years
expect([1, 2, 3]).toEqual(expect.arrayContaining([3, 3, 3]))
will still pass, so this should not be used. -
Hannes Schneidermayer about 2 yearsthis is the only way to go
-
Shachar Har-Shuv about 2 yearsThis should not be the first answer as it's outdated. Please see answer below regarding arrayWithExactContents