Expect Arrays to be equal ignoring order

jest expect array equal
deep-equal-in-any-order
jest compare array of objects
jest expect any function
jest toincludesamemembers
chai deep equal in any order
jest expect contains array
chai deep equal not working

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

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());

A matcher that checks that two arrays contain the same elements , toMatchArray([2, 1]) // order doesn't matter! expect([1, 2, 2]). Possible solution: Given arrays A and B, check that they are equal in length. javascript - objects - Expect Arrays to be equal ignoring order For what it's worth, in Jest you can do: Here's a solution that will work for any number or arrays Some tests (a few answers to this question don't account for arrays with multiple items of the same value, so [1, 2, 2] and [1, 2] would incorrectly return true)

// 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)

deep-equal-in-any-order, It works in similar way as deep.equal but it doesn't checks the arrays order (at chai.use(deepEqualInAnyOrder); const { expect } = chai; expect([1, 2]).to.deep. For expect, .equal will compare objects rather than their data, and in your case it is two different arrays. Use .eql in order to deeply compare values. Check out this link. Or you could use .deep.equal in order to simulate same as .eql. Or in your case you might want to check.members. For asserts you can use .deepEqual, link.

simple...

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqual(jasmine.arrayContaining(array2));

Testing Arrays and Objects with Chai.js - Building Ibotta, When it comes to testing arrays and objects with Chai.js sometimes the expect​([1, 2, 3]).to.equal([1, 2, 3]); // fails Deep equality is an excellent approach, but it enforces both order and contents when comparing arrays. Both objects are Arrays and both arrays have a length of 2 and both have a value on the first index and both have undefined on the second index. After playing around a little it maybe is a question what do we call equal. Same behavior or identical structure.

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

Using Matchers · Jest, matchers. For the full list, see the [`expect` API doc](/docs/en/expect). The simplest way to test a value is with exact equality. test('two toBe uses Object.is to test exact equality. toEqual recursively checks every field of an object or array. expect.not.arrayContaining(array) expect.not.arrayContaining(array) matches a received array which does not contain all of the elements in the expected array. That is, the expected array is not a subset of the received array. It is the inverse of expect.arrayContaining.

//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;
}

Check if two arrays contain the same elements in Ruby, RSpec or , To test whether two arrays have the same elements regardless of order, RSpec 1 and 2 give With RSpec 3's expect syntax you can choose one of these two matchers: If you're OK with ignoring duplicate elements and your element classes  The contain_exactly matcher provides a way to test arrays against each other in a way that disregards differences in the ordering between the actual and expected array. For example: expect([1, 2, 3]).to contain_exactly(2, 3, 1) # pass expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail

Array.prototype.sort(), The default sort order is ascending, built upon converting the elements into strings, then expected output: Array [1, 100000, 21, 30, 4]. 10. ​ if (a is greater than b by the ordering criterion) { return 1; } // a must be equal to b return 0; } toUpperCase(); // ignore upper and lowercase var nameB = b.name. Structures — Fields need not be in the same order as long as the contents are equal. Ordinal categorical arrays — Must have the same sets of categories, including their order. Categorical arrays that are not ordinal — Can have different sets of categories, and isequal compares the category names of each pair of elements.

General constraint to compare for equality - MATLAB, If the expected value is a MATLAB or Java object, the IsEqualTo constraint calls the You can specify several name-value pair arguments in any order as Name1,Value1 Fields to ignore during struct comparison, specified as a cell array of  However, it’s often best to assert that the target is deeply equal to its expected value, rather than not deeply equal to one of countless unexpected values.

array_diff - Manual, my alternative method for evaluating if two arrays contain (all) identical values: <?​php to what you might expect; in my case the order of elements had no importance. If we need to find array in the multidimenssional array (with ignore keys!) Built in matchers. rspec-expectations ships with a number of built-in matchers. Each matcher can be used with expect(..).to or expect(..).not_to to define positive and negative expectations

Comments
  • expect(array1.sort()).toEqual(array2.sort()); ?
  • @raina77ow I guess that would work as well.
  • Should I make this an answer?
  • @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.
  • I 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.
  • the default array sort method uses string comparison for numbers. "10" < "2" === true
  • [10, 2, 1].sort() ---> [1, 10, 2]
  • @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.
  • Fair point. It is worth noting that sort happens in-place, though. (it mutates the instance on which it is called)
  • @Shmiddty that's true, but .map returns a new array, so you're still not mutating the original.
  • Use .forEach instead of .map to save some time and a bunch of memory.
  • Unfortunately this will pass with the following arrays even though they are different: array1 = [1, 2], array2 = [1, 1]
  • Nice catch @redbmk I added a check for this, thanks!
  • I 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.