开发者

Javascript Arrays - Checking two arrays of objects for same contents, ignoring order

开发者 https://www.devze.com 2023-01-07 06:07 出处:网络
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.

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 ar开发者_如何学运维e 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).


If the duplicates do not matter, you can make an one-liner by using lodash. Look if the difference between two arrays is empty.

if (_(array).difference(otherArray).isEmpty()) {
    // is equal ignoring order and duplicates
}

console.log(_([1,2,3]).difference([2,3,1]).isEmpty()) // -> true
console.log(_([1,2,3,3]).difference([2,3,1,1]).isEmpty()) // -> also true


With ES6 you could use every and some (and length).

let A = [1, 2, 3];
let B = [2, 3, 1];

// all objects in A are contained in B (A ⊆ B)
// you can compare a <-> b however you'd like (here just `a === b`)
let AsubB = A.every(a => B.some(b => a === b));

// A and B are the same length
let sameLength = A.length === B.length;

// their contents are as equal as previously tested:
let equal = AsubB && sameLength;


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


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.


Simple & Elegant

function isEqual(arr1, arr2) {
    if (arr1.length !== arr2.length)
        return false;
    return arr1.every(x => arr2.includes(x));
}

If duplication is important, use this

function isEqual(arr1, arr2) {
    if (arr1.length !== arr2.length)
        return false;
    arr1.sort();
    arr2.sort();
    for (var i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i])
            return false;
    }
    return true;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消