views:

95

answers:

2

I have two JavaScript arrays (A and B) that contain objects that I created. I want to check that all the objects in array A are contained in array B, but not necessarily in the same order.

What is the best way to do this?

Edit:

They are all actual objects, not primitives, so I will need to compare their contents and structure as well (maybe using something like JSON.stringify).

I want to do this because I'm learning Test-Driven Development, and I want to test functions that return lists of objects. I need to test whether the returned lists have the expected objects in them or not (order doesn't matter in this case).

+1  A: 

This is probably the simplest method if not the slowest.

var o = { PropA: 1, PropB: 2 };
var a = [1, 2, 3, 4, o];
var b = [2, 3, 4, 1];

var c = a.filter(function(value, index, obj) {
    return b.indexOf(value) > -1;
});

if (c.length !== a.length) {
    throw new Error("Array b is missing some elements!");
}

indexOf will only check that they refer to the same object. If you want to check value equivalence you will have to do a deep compare of the properties or use JSON.stringify as you mention in your question.

ChaosPandion
Does `.indexOf` check for object equivalency too? As in, if I make an `o2 = { PropA: 2, PropB: 2}` and put it in `b`, would it return something other than `-1`?
Chetan
@Chetan - See update.
ChaosPandion
A: 

Usage: isEqArrays(arr1, arr2)

//
// Array comparsion
//

function inArray(array, el) {
  for ( var i = array.length; i--; ) {
    if ( array[i] === el ) return true;
  }
  return false;
}

function isEqArrays(arr1, arr2) {
  if ( arr1.length !== arr2.length ) {
    return false;
  }
  for ( var i = arr1.length; i--; ) {
    if ( !inArray( arr2, arr1[i] ) ) {
      return false;
    }
  }
  return true;
}
galambalazs
Is this faster than @ChaosPandion's solution?
Chetan
it's cross browser. Chaos's isn't. He uses language features which are not well-supported yet.
galambalazs