Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two arrays which contain objects

I have two arrays which only contain objects for groups. One contains all the groups on my site. The other contains all the groups a specific user belongs to.

I'd like to subtract: All the groups - user groups = groups remaining

I'm using AngularJS, I'm not sure if that helps here or not (maybe a filter could be used).

I looked at previous questions and came across some options:

These are the ones I tried:

$scope.availableGroups =  $($scope.groups).not($scope.assignedGroups).get();
$scope.availableGroups = $.grep($scope.groups,function(x) {return $.inArray(x, $scope.assignedGroups) < 0})

This is one of the arrays:

assignedGroups:

[{
    id: 115,
    name: 'Test Group 2',
    Description: '',
    owner: 10,
    OwnerIsUser: false,
}, {
    id: 116,
    name: 'Test Group 3',
    Description: '',
    owner: 71,
    OwnerIsUser: false,
}, {
    id: 117,
    name: 'Test Group 4',
    Description: '',
    owner: 71,
    OwnerIsUser: false,
}, {
    id: 118,
    name: 'Test Group 5',
    Description: '',
    owner: 115,
    OwnerIsUser: false,
}, {
    id: 119,
    name: 'Test Group 6',
    Description: '',
    owner: 8,
    OwnerIsUser: true,
}];
like image 709
Batman Avatar asked Jan 19 '14 07:01

Batman


People also ask

How do I compare the contents of two arrays?

Programmers who wish to compare the contents of two arrays must use the static two-argument Arrays. equals() method. This method considers two arrays equivalent if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equivalent, according to Object. equals() .

How do I compare two arrays of arrays?

Using Arrays. equals(array1, array2) methods − This method iterates over each value of an array and compare using equals method. Using Arrays. deepEquals(array1, array2) methods − This method iterates over each value of an array and deep compare using any overridden equals method.

How do you check if two arrays contains same values?

The Arrays. equals() method checks the equality of the two arrays in terms of size, data, and order of elements. This method will accept the two arrays which need to be compared, and it returns the boolean result true if both the arrays are equal and false if the arrays are not equal.


2 Answers

I think you should extract ids to an object first and then compare two objects. Eg:

var assignedGroupsIds = {};
var groupsIds = {};
var result = [];

$scope.assignedGroups.forEach(function (el, i) {
  assignedGroupsIds[el.id] = $scope.assignedGroups[i];
});

$scope.groups.forEach(function (el, i) {
  groupsIds[el.id] = $scope.groups[i];
});

for (var i in groupsIds) {
    if (!assignedGroupsIds.hasOwnProperty(i)) {
        result.push(groupsIds[i]);
    }
}

return result;

Here goes simplified fiddle: http://jsfiddle.net/NLQGL/2/ Adjust it to your needs.

I think it's a good solution since you could reuse the groupsIds object (it seems not to change often).

Note: Feel free to use angular.forEach() instead of Array.prototype.forEach

like image 155
Michał Miszczyszyn Avatar answered Sep 19 '22 21:09

Michał Miszczyszyn


You can use a combination of Angular JS's $filter service and Lo-dash's findWhere method to get unique objects in two arrays, try this :

// When you don't know the lengths of the arrays you want to compare
    var allTheGroupsLength = allTheGroups.length;
    var userGroupsLength = userGroups.length;
    var groupsRemaining = [];

    if(allTheGroupsLength > userGroupsLength){
        getDifference(allTheGroups, userGroups);
    }
    else{
        getDifference(userGroups, allTheGroups);
    }

    function getDifference(obj1, obj2){
        groupsRemaining  = $filter('filter')(obj1, function(obj1Value){
              return !Boolean(_.findWhere(obj2, obj1Value));
        });
    }

OR

//All the groups - user groups = groups remaining

 groupsRemaining  = $filter('filter')(allTheGroups, function(allTheGroupsObj){
                  return !Boolean(_.findWhere(userGroups, allTheGroupsObj));
              });

Using only Angular JS

  groupsRemaining =  $filter('filter')(allTheGroups, function(allTheGroupsObj){
                      return !angular.equals(allTheGroupsObj, $filter('filter')(userGroups, function(userGroupsObj){
                      return angular.equals(allTheGroupsObj,userGroupsObj);})[0]);
                  });
like image 44
Ajay Ullal Avatar answered Sep 21 '22 21:09

Ajay Ullal